diff options
author | bunnei <bunneidev@gmail.com> | 2014-10-08 00:56:40 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2014-10-25 20:11:41 +0200 |
commit | 818ba32746072af65a7b5ac0f1712bde3388f641 (patch) | |
tree | e11104887d1a680e3aa33bddc4ad3ca764ead696 /src/core | |
parent | ARM: Removed unused armos code from SkyEye. (diff) | |
download | yuzu-818ba32746072af65a7b5ac0f1712bde3388f641.tar yuzu-818ba32746072af65a7b5ac0f1712bde3388f641.tar.gz yuzu-818ba32746072af65a7b5ac0f1712bde3388f641.tar.bz2 yuzu-818ba32746072af65a7b5ac0f1712bde3388f641.tar.lz yuzu-818ba32746072af65a7b5ac0f1712bde3388f641.tar.xz yuzu-818ba32746072af65a7b5ac0f1712bde3388f641.tar.zst yuzu-818ba32746072af65a7b5ac0f1712bde3388f641.zip |
Diffstat (limited to 'src/core')
22 files changed, 326 insertions, 7743 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index cc0deb004..aefbe3375 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -6,19 +6,10 @@ set(SRCS arm/dyncom/arm_dyncom_interpreter.cpp arm/dyncom/arm_dyncom_run.cpp arm/dyncom/arm_dyncom_thumb.cpp - arm/interpreter/mmu/arm1176jzf_s_mmu.cpp - arm/interpreter/mmu/cache.cpp - arm/interpreter/mmu/maverick.cpp - arm/interpreter/mmu/rb.cpp - arm/interpreter/mmu/sa_mmu.cpp - arm/interpreter/mmu/tlb.cpp - arm/interpreter/mmu/wb.cpp - arm/interpreter/mmu/xscale_copro.cpp arm/interpreter/arm_interpreter.cpp arm/interpreter/armcopro.cpp arm/interpreter/armemu.cpp arm/interpreter/arminit.cpp - arm/interpreter/armmmu.cpp arm/interpreter/armsupp.cpp arm/interpreter/armvirt.cpp arm/interpreter/thumbemu.cpp @@ -72,12 +63,6 @@ set(HEADERS arm/dyncom/arm_dyncom_run.h arm/dyncom/arm_dyncom_thumb.h arm/interpreter/arm_interpreter.h - arm/interpreter/mmu/arm1176jzf_s_mmu.h - arm/interpreter/mmu/cache.h - arm/interpreter/mmu/rb.h - arm/interpreter/mmu/sa_mmu.h - arm/interpreter/mmu/tlb.h - arm/interpreter/mmu/wb.h arm/skyeye_common/arm_regformat.h arm/skyeye_common/armcpu.h arm/skyeye_common/armdefs.h diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 7a65669ef..669b612fc 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -27,7 +27,6 @@ ARM_DynCom::ARM_DynCom() : ticks(0) { ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); state->lateabtSig = LOW; - mmu_init(state); // Reset the core to initial state ARMul_CoProInit(state.get()); diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp index 6f6a5913c..ed4415082 100644 --- a/src/core/arm/interpreter/arm_interpreter.cpp +++ b/src/core/arm/interpreter/arm_interpreter.cpp @@ -22,7 +22,6 @@ ARM_Interpreter::ARM_Interpreter() { ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); state->lateabtSig = LOW; - mmu_init(state); // Reset the core to initial state ARMul_CoProInit(state); diff --git a/src/core/arm/interpreter/armcopro.cpp b/src/core/arm/interpreter/armcopro.cpp index 9de6651d4..b4ddc3d96 100644 --- a/src/core/arm/interpreter/armcopro.cpp +++ b/src/core/arm/interpreter/armcopro.cpp @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #include "core/arm/skyeye_common/armdefs.h" #include "core/arm/skyeye_common/armemu.h" #include "core/arm/skyeye_common/vfp/vfp.h" @@ -25,817 +24,302 @@ //chy ------- //#include "iwmmxt.h" - -//chy 2005-09-19 add CP6 MRC support (for get irq number and base) -extern unsigned xscale_cp6_mrc (ARMul_State * state, unsigned type, - ARMword instr, ARMword * data); -//chy 2005-09-19--------------- - -extern unsigned xscale_cp13_init (ARMul_State * state); -extern unsigned xscale_cp13_exit (ARMul_State * state); -extern unsigned xscale_cp13_ldc (ARMul_State * state, unsigned type, - ARMword instr, ARMword data); -extern unsigned xscale_cp13_stc (ARMul_State * state, unsigned type, - ARMword instr, ARMword * data); -extern unsigned xscale_cp13_mrc (ARMul_State * state, unsigned type, - ARMword instr, ARMword * data); -extern unsigned xscale_cp13_mcr (ARMul_State * state, unsigned type, - ARMword instr, ARMword data); -extern unsigned xscale_cp13_cdp (ARMul_State * state, unsigned type, - ARMword instr); -extern unsigned xscale_cp13_read_reg (ARMul_State * state, unsigned reg, - ARMword * data); -extern unsigned xscale_cp13_write_reg (ARMul_State * state, unsigned reg, - ARMword data); -extern unsigned xscale_cp14_init (ARMul_State * state); -extern unsigned xscale_cp14_exit (ARMul_State * state); -extern unsigned xscale_cp14_ldc (ARMul_State * state, unsigned type, - ARMword instr, ARMword data); -extern unsigned xscale_cp14_stc (ARMul_State * state, unsigned type, - ARMword instr, ARMword * data); -extern unsigned xscale_cp14_mrc (ARMul_State * state, unsigned type, - ARMword instr, ARMword * data); -extern unsigned xscale_cp14_mcr (ARMul_State * state, unsigned type, - ARMword instr, ARMword data); -extern unsigned xscale_cp14_cdp (ARMul_State * state, unsigned type, - ARMword instr); -extern unsigned xscale_cp14_read_reg (ARMul_State * state, unsigned reg, - ARMword * data); -extern unsigned xscale_cp14_write_reg (ARMul_State * state, unsigned reg, - ARMword data); -extern unsigned xscale_cp15_init (ARMul_State * state); -extern unsigned xscale_cp15_exit (ARMul_State * state); -extern unsigned xscale_cp15_ldc (ARMul_State * state, unsigned type, - ARMword instr, ARMword data); -extern unsigned xscale_cp15_stc (ARMul_State * state, unsigned type, - ARMword instr, ARMword * data); -extern unsigned xscale_cp15_mrc (ARMul_State * state, unsigned type, - ARMword instr, ARMword * data); -extern unsigned xscale_cp15_mcr (ARMul_State * state, unsigned type, - ARMword instr, ARMword data); -extern unsigned xscale_cp15_cdp (ARMul_State * state, unsigned type, - ARMword instr); -extern unsigned xscale_cp15_read_reg (ARMul_State * state, unsigned reg, - ARMword * data); -extern unsigned xscale_cp15_write_reg (ARMul_State * state, unsigned reg, - ARMword data); -extern unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg, - unsigned cpnum); - /* Dummy Co-processors. */ static unsigned -NoCoPro3R (ARMul_State * state, - unsigned a, ARMword b) +NoCoPro3R(ARMul_State * state, +unsigned a, ARMword b) { - return ARMul_CANT; + return ARMul_CANT; } static unsigned -NoCoPro4R (ARMul_State * state, - unsigned a, - ARMword b, ARMword c) +NoCoPro4R(ARMul_State * state, +unsigned a, +ARMword b, ARMword c) { - return ARMul_CANT; + return ARMul_CANT; } static unsigned -NoCoPro4W (ARMul_State * state, - unsigned a, - ARMword b, ARMword * c) +NoCoPro4W(ARMul_State * state, +unsigned a, +ARMword b, ARMword * c) { - return ARMul_CANT; + return ARMul_CANT; } static unsigned -NoCoPro5R (ARMul_State * state, - unsigned a, - ARMword b, - ARMword c, ARMword d) +NoCoPro5R(ARMul_State * state, +unsigned a, +ARMword b, +ARMword c, ARMword d) { - return ARMul_CANT; + return ARMul_CANT; } static unsigned -NoCoPro5W (ARMul_State * state, - unsigned a, - ARMword b, - ARMword * c, ARMword * d ) +NoCoPro5W(ARMul_State * state, +unsigned a, +ARMword b, +ARMword * c, ARMword * d) { - return ARMul_CANT; + return ARMul_CANT; } /* The XScale Co-processors. */ /* Coprocessor 15: System Control. */ -static void write_cp14_reg (unsigned, ARMword); -static ARMword read_cp14_reg (unsigned); - -/* There are two sets of registers for copro 15. - One set is available when opcode_2 is 0 and - the other set when opcode_2 >= 1. */ -static ARMword XScale_cp15_opcode_2_is_0_Regs[16]; -static ARMword XScale_cp15_opcode_2_is_not_0_Regs[16]; -/* There are also a set of breakpoint registers - which are accessed via CRm instead of opcode_2. */ -static ARMword XScale_cp15_DBR1; -static ARMword XScale_cp15_DBCON; -static ARMword XScale_cp15_IBCR0; -static ARMword XScale_cp15_IBCR1; - -static unsigned -XScale_cp15_init (ARMul_State * state) -{ - int i; - - for (i = 16; i--;) { - XScale_cp15_opcode_2_is_0_Regs[i] = 0; - XScale_cp15_opcode_2_is_not_0_Regs[i] = 0; - } - - /* Initialise the processor ID. */ - //chy 2003-03-24, is same as cpu id in skyeye_options.c - //XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000; - XScale_cp15_opcode_2_is_0_Regs[0] = 0x69050000; - - /* Initialise the cache type. */ - XScale_cp15_opcode_2_is_not_0_Regs[0] = 0x0B1AA1AA; - - /* Initialise the ARM Control Register. */ - XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078; - - return No_exp; -} - -/* Check an access to a register. */ - -static unsigned -check_cp15_access (ARMul_State * state, - unsigned reg, - unsigned CRm, unsigned opcode_1, unsigned opcode_2) -{ - /* Do not allow access to these register in USER mode. */ - //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode - if (state->Mode == USER26MODE || state->Mode == USER32MODE ) - return ARMul_CANT; - - /* Opcode_1should be zero. */ - if (opcode_1 != 0) - return ARMul_CANT; - - /* Different register have different access requirements. */ - switch (reg) { - case 0: - case 1: - /* CRm must be 0. Opcode_2 can be anything. */ - if (CRm != 0) - return ARMul_CANT; - break; - case 2: - case 3: - /* CRm must be 0. Opcode_2 must be zero. */ - if ((CRm != 0) || (opcode_2 != 0)) - return ARMul_CANT; - break; - case 4: - /* Access not allowed. */ - return ARMul_CANT; - case 5: - case 6: - /* Opcode_2 must be zero. CRm must be 0. */ - if ((CRm != 0) || (opcode_2 != 0)) - return ARMul_CANT; - break; - case 7: - /* Permissable combinations: - Opcode_2 CRm - 0 5 - 0 6 - 0 7 - 1 5 - 1 6 - 1 10 - 4 10 - 5 2 - 6 5 */ - switch (opcode_2) { - default: - return ARMul_CANT; - case 6: - if (CRm != 5) - return ARMul_CANT; - break; - case 5: - if (CRm != 2) - return ARMul_CANT; - break; - case 4: - if (CRm != 10) - return ARMul_CANT; - break; - case 1: - if ((CRm != 5) && (CRm != 6) && (CRm != 10)) - return ARMul_CANT; - break; - case 0: - if ((CRm < 5) || (CRm > 7)) - return ARMul_CANT; - break; - } - break; - - case 8: - /* Permissable combinations: - Opcode_2 CRm - 0 5 - 0 6 - 0 7 - 1 5 - 1 6 */ - if (opcode_2 > 1) - return ARMul_CANT; - if ((CRm < 5) || (CRm > 7)) - return ARMul_CANT; - if (opcode_2 == 1 && CRm == 7) - return ARMul_CANT; - break; - case 9: - /* Opcode_2 must be zero or one. CRm must be 1 or 2. */ - if (((CRm != 0) && (CRm != 1)) - || ((opcode_2 != 1) && (opcode_2 != 2))) - return ARMul_CANT; - break; - case 10: - /* Opcode_2 must be zero or one. CRm must be 4 or 8. */ - if (((CRm != 0) && (CRm != 1)) - || ((opcode_2 != 4) && (opcode_2 != 8))) - return ARMul_CANT; - break; - case 11: - /* Access not allowed. */ - return ARMul_CANT; - case 12: - /* Access not allowed. */ - return ARMul_CANT; - case 13: - /* Opcode_2 must be zero. CRm must be 0. */ - if ((CRm != 0) || (opcode_2 != 0)) - return ARMul_CANT; - break; - case 14: - /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */ - if (opcode_2 != 0) - return ARMul_CANT; - - if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8) - && (CRm != 9)) - return ARMul_CANT; - break; - case 15: - /* Opcode_2 must be zero. CRm must be 1. */ - if ((CRm != 1) || (opcode_2 != 0)) - return ARMul_CANT; - break; - default: - /* Should never happen. */ - return ARMul_CANT; - } - - return ARMul_DONE; -} - -/* Coprocessor 13: Interrupt Controller and Bus Controller. */ - -/* There are two sets of registers for copro 13. - One set (of three registers) is available when CRm is 0 - and the other set (of six registers) when CRm is 1. */ - -static ARMword XScale_cp13_CR0_Regs[16]; -static ARMword XScale_cp13_CR1_Regs[16]; - -static unsigned -XScale_cp13_init (ARMul_State * state) -{ - int i; - - for (i = 16; i--;) { - XScale_cp13_CR0_Regs[i] = 0; - XScale_cp13_CR1_Regs[i] = 0; - } - - return No_exp; -} - -/* Check an access to a register. */ - -static unsigned -check_cp13_access (ARMul_State * state, - unsigned reg, - unsigned CRm, unsigned opcode_1, unsigned opcode_2) -{ - /* Do not allow access to these registers in USER mode. */ - //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode - if (state->Mode == USER26MODE || state->Mode == USER32MODE ) - return ARMul_CANT; - - /* The opcodes should be zero. */ - if ((opcode_1 != 0) || (opcode_2 != 0)) - return ARMul_CANT; - - /* Do not allow access to these register if bit - 13 of coprocessor 15's register 15 is zero. */ - if (!CP_ACCESS_ALLOWED (state, 13)) - return ARMul_CANT; - - /* Registers 0, 4 and 8 are defined when CRm == 0. - Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1. - For all other CRm values undefined behaviour results. */ - if (CRm == 0) { - if (reg == 0 || reg == 4 || reg == 8) - return ARMul_DONE; - } - else if (CRm == 1) { - if (reg == 0 || reg == 1 || (reg >= 4 && reg <= 8)) - return ARMul_DONE; - } - - return ARMul_CANT; -} - -/* Coprocessor 14: Performance Monitoring, Clock and Power management, - Software Debug. */ - -static ARMword XScale_cp14_Regs[16]; - -static unsigned -XScale_cp14_init (ARMul_State * state) -{ - int i; - - for (i = 16; i--;) - XScale_cp14_Regs[i] = 0; - - return No_exp; -} +static void write_cp14_reg(unsigned, ARMword); +static ARMword read_cp14_reg(unsigned); /* Check an access to a register. */ static unsigned -check_cp14_access (ARMul_State * state, - unsigned reg, - unsigned CRm, unsigned opcode1, unsigned opcode2) -{ - /* Not allowed to access these register in USER mode. */ - //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode - if (state->Mode == USER26MODE || state->Mode == USER32MODE ) - return ARMul_CANT; - - /* CRm should be zero. */ - if (CRm != 0) - return ARMul_CANT; - - /* OPcodes should be zero. */ - if (opcode1 != 0 || opcode2 != 0) - return ARMul_CANT; - - /* Accessing registers 4 or 5 has unpredicatable results. */ - if (reg >= 4 && reg <= 5) - return ARMul_CANT; - - return ARMul_DONE; -} - -/* Here's ARMulator's MMU definition. A few things to note: - 1) It has eight registers, but only two are defined. - 2) You can only access its registers with MCR and MRC. - 3) MMU Register 0 (ID) returns 0x41440110 - 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4 - controls 32/26 bit program space, bit 5 controls 32/26 bit data space, - bit 6 controls late abort timimg and bit 7 controls big/little endian. */ - -static ARMword MMUReg[8]; - -static unsigned -MMUInit (ARMul_State * state) -{ -/* 2004-05-09 chy -------------------------------------------------------------- -read ARM Architecture Reference Manual -2.6.5 Data Abort -There are three Abort Model in ARM arch. - -Early Abort Model: used in some ARMv3 and earlier implementations. In this -model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and -the base register was unchanged for all other instructions. (oldest) - -Base Restored Abort Model: If a Data Abort occurs in an instruction which -specifies base register writeback, the value in the base register is -unchanged. (strongarm, xscale) - -Base Updated Abort Model: If a Data Abort occurs in an instruction which -specifies base register writeback, the base register writeback still occurs. -(arm720T) - -read PART B -chap2 The System Control Coprocessor CP15 -2.4 Register1:control register -L(bit 6): in some ARMv3 and earlier implementations, the abort model of the -processor could be configured: -0=early Abort Model Selected(now obsolete) -1=Late Abort Model selceted(same as Base Updated Abort Model) - -on later processors, this bit reads as 1 and ignores writes. -------------------------------------------------------------- -So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) - if lateabtSig=0, then it means Base Restored Abort Model -because the ARMs which skyeye simulates are all belonged to ARMv4, -so I think MMUReg[1]'s bit 6 should always be 1 - -*/ - - MMUReg[1] = state->prog32Sig << 4 | - state->data32Sig << 5 | 1 << 6 | state->bigendSig << 7; - //state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7; - - - NOTICE_LOG(ARM11, "ARMul_ConsolePrint: MMU present"); - - return TRUE; -} - -static unsigned -MMUMRC (ARMul_State * state, unsigned type, - ARMword instr, ARMword * value) -{ - mmu_mrc (state, instr, value); - return (ARMul_DONE); -} - -static unsigned -MMUMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value) -{ - mmu_mcr (state, instr, value); - return (ARMul_DONE); -} - -/* What follows is the Validation Suite Coprocessor. It uses two - co-processor numbers (4 and 5) and has the follwing functionality. - Sixteen registers. Both co-processor nuimbers can be used in an MCR - and MRC to access these registers. CP 4 can LDC and STC to and from - the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of - cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a - number of cycles (specified in a CP register), CDP 2 issues an IRQW - in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5 - stores a 32 bit time value in a CP register (actually it's the total - number of N, S, I, C and F cyles). */ - -static ARMword ValReg[16]; - -static unsigned -ValLDC (ARMul_State * state, - unsigned type, ARMword instr, ARMword data) -{ - static unsigned words; - - if (type != ARMul_DATA) - words = 0; - else { - ValReg[BITS (12, 15)] = data; - - if (BIT (22)) - /* It's a long access, get two words. */ - if (words++ != 4) - return ARMul_INC; - } - - return ARMul_DONE; -} - -static unsigned -ValSTC (ARMul_State * state, - unsigned type, ARMword instr, ARMword * data) -{ - static unsigned words; - - if (type != ARMul_DATA) - words = 0; - else { - *data = ValReg[BITS (12, 15)]; - - if (BIT (22)) - /* It's a long access, get two words. */ - if (words++ != 4) - return ARMul_INC; - } - - return ARMul_DONE; -} - -static unsigned -ValMRC (ARMul_State * state, - unsigned type, ARMword instr, ARMword * value) -{ - *value = ValReg[BITS (16, 19)]; - - return ARMul_DONE; -} - -static unsigned -ValMCR (ARMul_State * state, - unsigned type, ARMword instr, ARMword value) -{ - ValReg[BITS (16, 19)] = value; - - return ARMul_DONE; -} - -static unsigned -ValCDP (ARMul_State * state, unsigned type, ARMword instr) -{ - static unsigned int finish = 0; - - if (BITS (20, 23) != 0) - return ARMul_CANT; - - if (type == ARMul_FIRST) { - ARMword howlong; - - howlong = ValReg[BITS (0, 3)]; - - /* First cycle of a busy wait. */ - finish = ARMul_Time (state) + howlong; - - return howlong == 0 ? ARMul_DONE : ARMul_BUSY; - } - else if (type == ARMul_BUSY) { - if (ARMul_Time (state) >= finish) - return ARMul_DONE; - else - return ARMul_BUSY; - } - - return ARMul_CANT; -} - -static unsigned -DoAFIQ (ARMul_State * state) -{ - state->NfiqSig = LOW; - return 0; -} - -static unsigned -DoAIRQ (ARMul_State * state) -{ - state->NirqSig = LOW; - return 0; -} - -static unsigned -IntCDP (ARMul_State * state, unsigned type, ARMword instr) +check_cp15_access(ARMul_State * state, +unsigned reg, +unsigned CRm, unsigned opcode_1, unsigned opcode_2) { - static unsigned int finish; - ARMword howlong; - - howlong = ValReg[BITS (0, 3)]; - - switch ((int) BITS (20, 23)) { - case 0: - if (type == ARMul_FIRST) { - /* First cycle of a busy wait. */ - finish = ARMul_Time (state) + howlong; - - return howlong == 0 ? ARMul_DONE : ARMul_BUSY; - } - else if (type == ARMul_BUSY) { - if (ARMul_Time (state) >= finish) - return ARMul_DONE; - else - return ARMul_BUSY; - } - return ARMul_DONE; - - case 1: - if (howlong == 0) - ARMul_Abort (state, ARMul_FIQV); - else - ARMul_ScheduleEvent (state, howlong, DoAFIQ); - return ARMul_DONE; - - case 2: - if (howlong == 0) - ARMul_Abort (state, ARMul_IRQV); - else - ARMul_ScheduleEvent (state, howlong, DoAIRQ); - return ARMul_DONE; - - case 3: - state->NfiqSig = HIGH; - return ARMul_DONE; - - case 4: - state->NirqSig = HIGH; - return ARMul_DONE; - - case 5: - ValReg[BITS (0, 3)] = ARMul_Time (state); - return ARMul_DONE; - } - - return ARMul_CANT; + /* Do not allow access to these register in USER mode. */ + //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode + if (state->Mode == USER26MODE || state->Mode == USER32MODE) + return ARMul_CANT; + + /* Opcode_1should be zero. */ + if (opcode_1 != 0) + return ARMul_CANT; + + /* Different register have different access requirements. */ + switch (reg) { + case 0: + case 1: + /* CRm must be 0. Opcode_2 can be anything. */ + if (CRm != 0) + return ARMul_CANT; + break; + case 2: + case 3: + /* CRm must be 0. Opcode_2 must be zero. */ + if ((CRm != 0) || (opcode_2 != 0)) + return ARMul_CANT; + break; + case 4: + /* Access not allowed. */ + return ARMul_CANT; + case 5: + case 6: + /* Opcode_2 must be zero. CRm must be 0. */ + if ((CRm != 0) || (opcode_2 != 0)) + return ARMul_CANT; + break; + case 7: + /* Permissable combinations: + Opcode_2 CRm + 0 5 + 0 6 + 0 7 + 1 5 + 1 6 + 1 10 + 4 10 + 5 2 + 6 5 */ + switch (opcode_2) { + default: + return ARMul_CANT; + case 6: + if (CRm != 5) + return ARMul_CANT; + break; + case 5: + if (CRm != 2) + return ARMul_CANT; + break; + case 4: + if (CRm != 10) + return ARMul_CANT; + break; + case 1: + if ((CRm != 5) && (CRm != 6) && (CRm != 10)) + return ARMul_CANT; + break; + case 0: + if ((CRm < 5) || (CRm > 7)) + return ARMul_CANT; + break; + } + break; + + case 8: + /* Permissable combinations: + Opcode_2 CRm + 0 5 + 0 6 + 0 7 + 1 5 + 1 6 */ + if (opcode_2 > 1) + return ARMul_CANT; + if ((CRm < 5) || (CRm > 7)) + return ARMul_CANT; + if (opcode_2 == 1 && CRm == 7) + return ARMul_CANT; + break; + case 9: + /* Opcode_2 must be zero or one. CRm must be 1 or 2. */ + if (((CRm != 0) && (CRm != 1)) + || ((opcode_2 != 1) && (opcode_2 != 2))) + return ARMul_CANT; + break; + case 10: + /* Opcode_2 must be zero or one. CRm must be 4 or 8. */ + if (((CRm != 0) && (CRm != 1)) + || ((opcode_2 != 4) && (opcode_2 != 8))) + return ARMul_CANT; + break; + case 11: + /* Access not allowed. */ + return ARMul_CANT; + case 12: + /* Access not allowed. */ + return ARMul_CANT; + case 13: + /* Opcode_2 must be zero. CRm must be 0. */ + if ((CRm != 0) || (opcode_2 != 0)) + return ARMul_CANT; + break; + case 14: + /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */ + if (opcode_2 != 0) + return ARMul_CANT; + + if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8) + && (CRm != 9)) + return ARMul_CANT; + break; + case 15: + /* Opcode_2 must be zero. CRm must be 1. */ + if ((CRm != 1) || (opcode_2 != 0)) + return ARMul_CANT; + break; + default: + /* Should never happen. */ + return ARMul_CANT; + } + + return ARMul_DONE; } /* Install co-processor instruction handlers in this routine. */ unsigned -ARMul_CoProInit (ARMul_State * state) +ARMul_CoProInit(ARMul_State * state) { - unsigned int i; - - /* Initialise tham all first. */ - for (i = 0; i < 16; i++) - ARMul_CoProDetach (state, i); - - /* Install CoPro Instruction handlers here. - The format is: - ARMul_CoProAttach (state, CP Number, Init routine, Exit routine - LDC routine, STC routine, MRC routine, MCR routine, - CDP routine, Read Reg routine, Write Reg routine). */ - if (state->is_ep9312) { - ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4, - DSPMRC4, DSPMCR4, NULL, NULL, DSPCDP4, NULL, NULL); - ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5, - DSPMRC5, DSPMCR5, NULL, NULL, DSPCDP5, NULL, NULL); - ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL, - DSPMRC6, DSPMCR6, NULL, NULL, DSPCDP6, NULL, NULL); - } - else { - ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC, - ValMRC, ValMCR, NULL, NULL, ValCDP, NULL, NULL); - - ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL, - ValMRC, ValMCR, NULL, NULL, IntCDP, NULL, NULL); - } - - if (state->is_XScale) { - //chy 2005-09-19, for PXA27x's CP6 - if (state->is_pxa27x) { - ARMul_CoProAttach (state, 6, NULL, NULL, - NULL, NULL, xscale_cp6_mrc, - NULL, NULL, NULL, NULL, NULL, NULL); - } - //chy 2005-09-19 end------------- - ARMul_CoProAttach (state, 13, xscale_cp13_init, - xscale_cp13_exit, xscale_cp13_ldc, - xscale_cp13_stc, xscale_cp13_mrc, - xscale_cp13_mcr, NULL, NULL, xscale_cp13_cdp, - xscale_cp13_read_reg, - xscale_cp13_write_reg); - - ARMul_CoProAttach (state, 14, xscale_cp14_init, - xscale_cp14_exit, xscale_cp14_ldc, - xscale_cp14_stc, xscale_cp14_mrc, - xscale_cp14_mcr, NULL, NULL, xscale_cp14_cdp, - xscale_cp14_read_reg, - xscale_cp14_write_reg); - //chy: 2003-08-24. - ARMul_CoProAttach (state, 15, xscale_cp15_init, - xscale_cp15_exit, xscale_cp15_ldc, - xscale_cp15_stc, xscale_cp15_mrc, - xscale_cp15_mcr, NULL, NULL, xscale_cp15_cdp, - xscale_cp15_read_reg, - xscale_cp15_write_reg); - } - else if (state->is_v6) { - ARMul_CoProAttach (state, 10, VFPInit, NULL, VFPLDC, VFPSTC, - VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL); - ARMul_CoProAttach (state, 11, VFPInit, NULL, VFPLDC, VFPSTC, - VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL); - - ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL, - MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL); - } - else { //all except xscale - ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL, - // MMUMRC, MMUMCR, NULL, MMURead, MMUWrite); - MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL); - } -//chy 2003-09-03 do it in future!!!!???? + unsigned int i; + + /* Initialise tham all first. */ + for (i = 0; i < 16; i++) + ARMul_CoProDetach(state, i); + + /* Install CoPro Instruction handlers here. + The format is: + ARMul_CoProAttach (state, CP Number, Init routine, Exit routine + LDC routine, STC routine, MRC routine, MCR routine, + CDP routine, Read Reg routine, Write Reg routine). */ + if (state->is_v6) { + ARMul_CoProAttach(state, 10, VFPInit, NULL, VFPLDC, VFPSTC, + VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL); + ARMul_CoProAttach(state, 11, VFPInit, NULL, VFPLDC, VFPSTC, + VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL); + + /*ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL, + MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);*/ + } + //chy 2003-09-03 do it in future!!!!???? #if 0 - if (state->is_iWMMXt) { - ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC, - NULL, NULL, IwmmxtCDP, NULL, NULL); - - ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, - IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, - NULL); - } + if (state->is_iWMMXt) { + ARMul_CoProAttach(state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC, + NULL, NULL, IwmmxtCDP, NULL, NULL); + + ARMul_CoProAttach(state, 1, NULL, NULL, NULL, NULL, + IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, + NULL); + } #endif - //----------------------------------------------------------------------------- - //chy 2004-05-25, found the user/system code visit CP 1,2, so I add below code. - ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, - ValMRC, ValMCR, NULL, NULL, NULL, NULL, NULL); - ARMul_CoProAttach (state, 2, NULL, NULL, ValLDC, ValSTC, - NULL, NULL, NULL, NULL, NULL, NULL, NULL); - //------------------------------------------------------------------------------ - /* No handlers below here. */ - - /* Call all the initialisation routines. */ - for (i = 0; i < 16; i++) - if (state->CPInit[i]) - (state->CPInit[i]) (state); - - return TRUE; + /* No handlers below here. */ + + /* Call all the initialisation routines. */ + for (i = 0; i < 16; i++) + if (state->CPInit[i]) + (state->CPInit[i]) (state); + + return TRUE; } /* Install co-processor finalisation routines in this routine. */ void -ARMul_CoProExit (ARMul_State * state) +ARMul_CoProExit(ARMul_State * state) { - register unsigned i; + register unsigned i; - for (i = 0; i < 16; i++) - if (state->CPExit[i]) - (state->CPExit[i]) (state); + for (i = 0; i < 16; i++) + if (state->CPExit[i]) + (state->CPExit[i]) (state); - for (i = 0; i < 16; i++) /* Detach all handlers. */ - ARMul_CoProDetach (state, i); + for (i = 0; i < 16; i++) /* Detach all handlers. */ + ARMul_CoProDetach(state, i); } /* Routines to hook Co-processors into ARMulator. */ void -ARMul_CoProAttach (ARMul_State * state, - unsigned number, - ARMul_CPInits * init, - ARMul_CPExits * exit, - ARMul_LDCs * ldc, - ARMul_STCs * stc, - ARMul_MRCs * mrc, - ARMul_MCRs * mcr, - ARMul_MRRCs * mrrc, - ARMul_MCRRs * mcrr, - ARMul_CDPs * cdp, - ARMul_CPReads * read, ARMul_CPWrites * write) -{ - if (init != NULL) - state->CPInit[number] = init; - if (exit != NULL) - state->CPExit[number] = exit; - if (ldc != NULL) - state->LDC[number] = ldc; - if (stc != NULL) - state->STC[number] = stc; - if (mrc != NULL) - state->MRC[number] = mrc; - if (mcr != NULL) - state->MCR[number] = mcr; - if (mrrc != NULL) - state->MRRC[number] = mrrc; - if (mcrr != NULL) - state->MCRR[number] = mcrr; - if (cdp != NULL) - state->CDP[number] = cdp; - if (read != NULL) - state->CPRead[number] = read; - if (write != NULL) - state->CPWrite[number] = write; -} - -void -ARMul_CoProDetach (ARMul_State * state, unsigned number) +ARMul_CoProAttach(ARMul_State * state, +unsigned number, +ARMul_CPInits * init, +ARMul_CPExits * exit, +ARMul_LDCs * ldc, +ARMul_STCs * stc, +ARMul_MRCs * mrc, +ARMul_MCRs * mcr, +ARMul_MRRCs * mrrc, +ARMul_MCRRs * mcrr, +ARMul_CDPs * cdp, +ARMul_CPReads * read, ARMul_CPWrites * write) { - ARMul_CoProAttach (state, number, NULL, NULL, - NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, - NoCoPro5W, NoCoPro5R, NoCoPro3R, NULL, NULL); - - state->CPInit[number] = NULL; - state->CPExit[number] = NULL; - state->CPRead[number] = NULL; - state->CPWrite[number] = NULL; + if (init != NULL) + state->CPInit[number] = init; + if (exit != NULL) + state->CPExit[number] = exit; + if (ldc != NULL) + state->LDC[number] = ldc; + if (stc != NULL) + state->STC[number] = stc; + if (mrc != NULL) + state->MRC[number] = mrc; + if (mcr != NULL) + state->MCR[number] = mcr; + if (mrrc != NULL) + state->MRRC[number] = mrrc; + if (mcrr != NULL) + state->MCRR[number] = mcrr; + if (cdp != NULL) + state->CDP[number] = cdp; + if (read != NULL) + state->CPRead[number] = read; + if (write != NULL) + state->CPWrite[number] = write; } -//chy 2003-09-03:below funs just replace the old ones - -/* Set the XScale FSR and FAR registers. */ - void -XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword _far) -{ - //if (!state->is_XScale || (read_cp14_reg (10) & (1UL << 31)) == 0) - if (!state->is_XScale) - return; - //assume opcode2=0 crm =0 - xscale_cp15_write_reg (state, 5, fsr); - xscale_cp15_write_reg (state, 6, _far); -} - -//chy 2003-09-03 seems 0 is CANT, 1 is DONE ???? -int -XScale_debug_moe (ARMul_State * state, int moe) +ARMul_CoProDetach(ARMul_State * state, unsigned number) { - //chy 2003-09-03 , W/R CP14 reg, now it's no use ???? - printf ("SKYEYE: XScale_debug_moe called !!!!\n"); - return 1; + ARMul_CoProAttach(state, number, NULL, NULL, + NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, + NoCoPro5W, NoCoPro5R, NoCoPro3R, NULL, NULL); + + state->CPInit[number] = NULL; + state->CPExit[number] = NULL; + state->CPRead[number] = NULL; + state->CPWrite[number] = NULL; } diff --git a/src/core/arm/interpreter/armmmu.cpp b/src/core/arm/interpreter/armmmu.cpp deleted file mode 100644 index 98fc17ddb..000000000 --- a/src/core/arm/interpreter/armmmu.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - armmmu.c - Memory Management Unit emulation. - ARMulator extensions for the ARM7100 family. - Copyright (C) 1999 Ben Williamson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include <assert.h> -#include <string.h> -#include "core/arm/skyeye_common/armdefs.h" -/* two header for arm disassemble */ -//#include "skyeye_arch.h" -#include "core/arm/skyeye_common/armcpu.h" - - -extern mmu_ops_t xscale_mmu_ops; -exception_t arm_mmu_write(short size, u32 addr, uint32_t *value); -exception_t arm_mmu_read(short size, u32 addr, uint32_t *value); -#define MMU_OPS (state->mmu.ops) -ARMword skyeye_cachetype = -1; - -int -mmu_init (ARMul_State * state) -{ - int ret; - - state->mmu.control = 0x70; - state->mmu.translation_table_base = 0xDEADC0DE; - state->mmu.domain_access_control = 0xDEADC0DE; - state->mmu.fault_status = 0; - state->mmu.fault_address = 0; - state->mmu.process_id = 0; - - switch (state->cpu->cpu_val & state->cpu->cpu_mask) { - //case SA1100: - //case SA1110: - // NOTICE_LOG(ARM11, "SKYEYE: use sa11xx mmu ops\n"); - // state->mmu.ops = sa_mmu_ops; - // break; - //case PXA250: - //case PXA270: //xscale - // NOTICE_LOG(ARM11, "SKYEYE: use xscale mmu ops\n"); - // state->mmu.ops = xscale_mmu_ops; - // break; - //case 0x41807200: //arm720t - //case 0x41007700: //arm7tdmi - //case 0x41007100: //arm7100 - // NOTICE_LOG(ARM11, "SKYEYE: use arm7100 mmu ops\n"); - // state->mmu.ops = arm7100_mmu_ops; - // break; - //case 0x41009200: - // NOTICE_LOG(ARM11, "SKYEYE: use arm920t mmu ops\n"); - // state->mmu.ops = arm920t_mmu_ops; - // break; - //case 0x41069260: - // NOTICE_LOG(ARM11, "SKYEYE: use arm926ejs mmu ops\n"); - // state->mmu.ops = arm926ejs_mmu_ops; - // break; - /* case 0x560f5810: */ - case 0x0007b000: - NOTICE_LOG(ARM11, "SKYEYE: use arm11jzf-s mmu ops\n"); - state->mmu.ops = arm1176jzf_s_mmu_ops; - break; - - default: - ERROR_LOG (ARM11, - "SKYEYE: armmmu.c : mmu_init: unknown cpu_val&cpu_mask 0x%x\n", - state->cpu->cpu_val & state->cpu->cpu_mask); - break; - - }; - ret = state->mmu.ops.init (state); - state->mmu_inited = (ret == 0); - /* initialize mmu_read and mmu_write for disassemble */ - //skyeye_config_t *config = get_current_config(); - //generic_arch_t *arch_instance = get_arch_instance(config->arch->arch_name); - //arch_instance->mmu_read = arm_mmu_read; - //arch_instance->mmu_write = arm_mmu_write; - - return ret; -} - -int -mmu_reset (ARMul_State * state) -{ - if (state->mmu_inited) - mmu_exit (state); - return mmu_init (state); -} - -void -mmu_exit (ARMul_State * state) -{ - MMU_OPS.exit (state); - state->mmu_inited = 0; -} - -fault_t -mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data) -{ - return MMU_OPS.read_byte (state, virt_addr, data); -}; - -fault_t -mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data) -{ - return MMU_OPS.read_halfword (state, virt_addr, data); -}; - -fault_t -mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data) -{ - return MMU_OPS.read_word (state, virt_addr, data); -}; - -fault_t -mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data) -{ - fault_t fault; - //static int count = 0; - //count ++; - fault = MMU_OPS.write_byte (state, virt_addr, data); - return fault; -} - -fault_t -mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data) -{ - fault_t fault; - //static int count = 0; - //count ++; - fault = MMU_OPS.write_halfword (state, virt_addr, data); - return fault; -} - -fault_t -mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data) -{ - fault_t fault; - fault = MMU_OPS.write_word (state, virt_addr, data); - - /*used for debug for MMU* - - if (!fault){ - ARMword tmp; - - if (mmu_read_word(state, virt_addr, &tmp)){ - err_msg("load back\n"); - exit(-1); - }else{ - if (tmp != data){ - err_msg("load back not equal %d %x\n", count, virt_addr); - } - } - } - */ - - return fault; -}; - -fault_t -mmu_load_instr (ARMul_State * state, ARMword virt_addr, ARMword * instr) -{ - return MMU_OPS.load_instr (state, virt_addr, instr); -} - -ARMword -mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value) -{ - return MMU_OPS.mrc (state, instr, value); -} - -void -mmu_mcr (ARMul_State * state, ARMword instr, ARMword value) -{ - MMU_OPS.mcr (state, instr, value); -} - -/*ywc 20050416*/ -int -mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr) -{ - return (MMU_OPS.v2p_dbct (state, virt_addr, phys_addr)); -} - -// -// -///* dis_mmu_read for disassemble */ -//exception_t arm_mmu_read(short size, uint32_t addr, uint32_t * value) -//{ -// ARMul_State *state; -// ARM_CPU_State *cpu = get_current_cpu(); -// state = &cpu->core[0]; -// switch(size){ -// case 8: -// MMU_OPS.read_byte (state, addr, value); -// break; -// case 16: -// case 32: -// break; -// default: -// ERROR_LOG(ARM11, "Error size %d", size); -// break; -// } -// return No_exp; -//} -///* dis_mmu_write for disassemble */ -//exception_t arm_mmu_write(short size, uint32_t addr, uint32_t *value) -//{ -// ARMul_State *state; -// ARM_CPU_State *cpu = get_current_cpu(); -// state = &cpu->core[0]; -// switch(size){ -// case 8: -// MMU_OPS.write_byte (state, addr, value); -// break; -// case 16: -// case 32: -// break; -// default: -// printf("In %s error size %d Line %d\n", __func__, size, __LINE__); -// break; -// } -// return No_exp; -//} diff --git a/src/core/arm/interpreter/armvirt.cpp b/src/core/arm/interpreter/armvirt.cpp index eb3c86cb4..7845d1042 100644 --- a/src/core/arm/interpreter/armvirt.cpp +++ b/src/core/arm/interpreter/armvirt.cpp @@ -24,657 +24,142 @@ freed as they might be needed again. A single area of memory may be defined to generate aborts. */ #include "core/arm/skyeye_common/armdefs.h" -#include "core/arm/skyeye_common/skyeye_defs.h" -//#include "code_cov.h" +#include "core/arm/skyeye_common/armemu.h" -#ifdef VALIDATE /* for running the validate suite */ -#define TUBE 48 * 1024 * 1024 /* write a char on the screen */ -#define ABORTS 1 -#endif - -/* #define ABORTS */ - -#ifdef ABORTS /* the memory system will abort */ -/* For the old test suite Abort between 32 Kbytes and 32 Mbytes - For the new test suite Abort between 8 Mbytes and 26 Mbytes */ -/* #define LOWABORT 32 * 1024 -#define HIGHABORT 32 * 1024 * 1024 */ -#define LOWABORT 8 * 1024 * 1024 -#define HIGHABORT 26 * 1024 * 1024 - -#endif - -#define NUMPAGES 64 * 1024 -#define PAGESIZE 64 * 1024 -#define PAGEBITS 16 -#define OFFSETBITS 0xffff -//chy 2003-08-19: seems no use ???? -int SWI_vector_installed = FALSE; -extern ARMword skyeye_cachetype; - -/***************************************************************************\ -* Get a byte into Virtual Memory, maybe allocating the page * -\***************************************************************************/ -static fault_t -GetByte (ARMul_State * state, ARMword address, ARMword * data) -{ - fault_t fault; - - fault = mmu_read_byte (state, address, data); - if (fault) { -//chy 2003-07-11: sometime has fault, but linux can continue running !!!!???? -// printf("SKYEYE: GetByte fault %d \n", fault); - } - return fault; -} - -/***************************************************************************\ -* Get a halfword into Virtual Memory, maybe allocating the page * -\***************************************************************************/ -static fault_t -GetHalfWord (ARMul_State * state, ARMword address, ARMword * data) -{ - fault_t fault; - - fault = mmu_read_halfword (state, address, data); - if (fault) { -//chy 2003-07-11: sometime has fault, but linux can continue running !!!!???? -// printf("SKYEYE: GetHalfWord fault %d \n", fault); - } - return fault; -} - -/***************************************************************************\ -* Get a Word from Virtual Memory, maybe allocating the page * -\***************************************************************************/ +#include "core/mem_map.h" -static fault_t -GetWord (ARMul_State * state, ARMword address, ARMword * data) -{ - fault_t fault; +#define dumpstack 1 +#define dumpstacksize 0x10 +#define maxdmupaddr 0x0033a850 - fault = mmu_read_word (state, address, data); - if (fault) { -//chy 2003-07-11: sometime has fault, but linux can continue running !!!!???? -#if 0 -/* XXX */ extern int hack; - hack = 1; -#endif -#if 0 - printf ("mmu_read_word at 0x%08x: ", address); - switch (fault) { - case ALIGNMENT_FAULT: - printf ("ALIGNMENT_FAULT"); - break; - case SECTION_TRANSLATION_FAULT: - printf ("SECTION_TRANSLATION_FAULT"); - break; - case PAGE_TRANSLATION_FAULT: - printf ("PAGE_TRANSLATION_FAULT"); - break; - case SECTION_DOMAIN_FAULT: - printf ("SECTION_DOMAIN_FAULT"); - break; - case SECTION_PERMISSION_FAULT: - printf ("SECTION_PERMISSION_FAULT"); - break; - case SUBPAGE_PERMISSION_FAULT: - printf ("SUBPAGE_PERMISSION_FAULT"); - break; - default: - printf ("Unrecognized fault number!"); - } - printf ("\tpc = 0x%08x\n", state->Reg[15]); -#endif - } - return fault; +/*ARMword ARMul_GetCPSR (ARMul_State * state) { +return 0; } - -//2003-07-10 chy: lyh change -/****************************************************************************\ - * Load a Instrion Word into Virtual Memory * -\****************************************************************************/ -static fault_t -LoadInstr (ARMul_State * state, ARMword address, ARMword * instr) -{ - fault_t fault; - fault = mmu_load_instr (state, address, instr); - return fault; - //if (fault) - // log_msg("load_instr fault = %d, address = %x\n", fault, address); +ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode) { +return 0; } +void ARMul_SetCPSR (ARMul_State * state, ARMword value) { -/***************************************************************************\ -* Put a byte into Virtual Memory, maybe allocating the page * -\***************************************************************************/ -static fault_t -PutByte (ARMul_State * state, ARMword address, ARMword data) -{ - fault_t fault; - - fault = mmu_write_byte (state, address, data); - if (fault) { -//chy 2003-07-11: sometime has fault, but linux can continue running !!!!???? -// printf("SKYEYE: PutByte fault %d \n", fault); - } - return fault; } +void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value) { -/***************************************************************************\ -* Put a halfword into Virtual Memory, maybe allocating the page * -\***************************************************************************/ -static fault_t -PutHalfWord (ARMul_State * state, ARMword address, ARMword data) -{ - fault_t fault; +}*/ - fault = mmu_write_halfword (state, address, data); - if (fault) { -//chy 2003-07-11: sometime has fault, but linux can continue running !!!!???? -// printf("SKYEYE: PutHalfWord fault %d \n", fault); - } - return fault; +void ARMul_Icycles(ARMul_State * state, unsigned number, ARMword address) { } -/***************************************************************************\ -* Put a Word into Virtual Memory, maybe allocating the page * -\***************************************************************************/ - -static fault_t -PutWord (ARMul_State * state, ARMword address, ARMword data) -{ - fault_t fault; - - fault = mmu_write_word (state, address, data); - if (fault) { -//chy 2003-07-11: sometime has fault, but linux can continue running !!!!???? -#if 0 -/* XXX */ extern int hack; - hack = 1; -#endif -#if 0 - printf ("mmu_write_word at 0x%08x: ", address); - switch (fault) { - case ALIGNMENT_FAULT: - printf ("ALIGNMENT_FAULT"); - break; - case SECTION_TRANSLATION_FAULT: - printf ("SECTION_TRANSLATION_FAULT"); - break; - case PAGE_TRANSLATION_FAULT: - printf ("PAGE_TRANSLATION_FAULT"); - break; - case SECTION_DOMAIN_FAULT: - printf ("SECTION_DOMAIN_FAULT"); - break; - case SECTION_PERMISSION_FAULT: - printf ("SECTION_PERMISSION_FAULT"); - break; - case SUBPAGE_PERMISSION_FAULT: - printf ("SUBPAGE_PERMISSION_FAULT"); - break; - default: - printf ("Unrecognized fault number!"); - } - printf ("\tpc = 0x%08x\n", state->Reg[15]); -#endif - } - return fault; +void ARMul_Ccycles(ARMul_State * state, unsigned number, ARMword address) { } -/***************************************************************************\ -* Initialise the memory interface * -\***************************************************************************/ - -unsigned -ARMul_MemoryInit (ARMul_State * state, unsigned int initmemsize) -{ - return TRUE; -} - -/***************************************************************************\ -* Remove the memory interface * -\***************************************************************************/ - -void -ARMul_MemoryExit (ARMul_State * state) -{ -} - -/***************************************************************************\ -* ReLoad Instruction * -\***************************************************************************/ - -ARMword -ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize) -{ - ARMword data; - fault_t fault; - -#ifdef ABORTS - if (address >= LOWABORT && address < HIGHABORT) { - ARMul_PREFETCHABORT (address); - return ARMul_ABORTWORD; - } - else { - ARMul_CLEARABORT; - } -#endif -#if 0 - /* do profiling for code coverage */ - if (skyeye_config.code_cov.prof_on) - cov_prof(EXEC_FLAG, address); -#endif -#if 1 - if ((isize == 2) && (address & 0x2)) { - ARMword lo, hi; - if (!(skyeye_cachetype == INSTCACHE)) - fault = GetHalfWord (state, address, &lo); - else - fault = LoadInstr (state, address, &lo); -#if 0 - if (!fault) { - if (!(skyeye_cachetype == INSTCACHE)) - fault = GetHalfWord (state, address + isize, &hi); - else - fault = LoadInstr (state, address + isize, &hi); - - } -#endif - if (fault) { - ARMul_PREFETCHABORT (address); - return ARMul_ABORTWORD; - } - else { - ARMul_CLEARABORT; - } - return lo; -#if 0 - if (state->bigendSig == HIGH) - return (lo << 16) | (hi >> 16); - else - return ((hi & 0xFFFF) << 16) | (lo >> 16); -#endif - } -#endif - if (!(skyeye_cachetype == INSTCACHE)) - fault = GetWord (state, address, &data); - else - fault = LoadInstr (state, address, &data); - - if (fault) { - - /* dyf add for s3c6410 no instcache temporary 2010.9.17 */ - if (!(skyeye_cachetype == INSTCACHE)) { - /* set translation fault on prefetch abort */ - state->mmu.fault_statusi = fault & 0xFF; - state->mmu.fault_address = address; - } - /* add end */ - - ARMul_PREFETCHABORT (address); - return ARMul_ABORTWORD; - } - else { - ARMul_CLEARABORT; - } - - return data; -} - -/***************************************************************************\ -* Load Instruction, Sequential Cycle * -\***************************************************************************/ - -ARMword -ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize) -{ - state->NumScycles++; +ARMword ARMul_LoadInstrS(ARMul_State * state, ARMword address, ARMword isize) { + state->NumScycles++; #ifdef HOURGLASS - if ((state->NumScycles & HOURGLASS_RATE) == 0) { - HOURGLASS; - } + if ((state->NumScycles & HOURGLASS_RATE) == 0) { + HOURGLASS; + } #endif - - return ARMul_ReLoadInstr (state, address, isize); + if (isize == 2) + return (u16)Memory::Read16(address); + else + return (u32)Memory::Read32(address); } -/***************************************************************************\ -* Load Instruction, Non Sequential Cycle * -\***************************************************************************/ - -ARMword -ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize) -{ - state->NumNcycles++; +ARMword ARMul_LoadInstrN(ARMul_State * state, ARMword address, ARMword isize) { + state->NumNcycles++; - return ARMul_ReLoadInstr (state, address, isize); + if (isize == 2) + return (u16)Memory::Read16(address); + else + return (u32)Memory::Read32(address); } -/***************************************************************************\ -* Read Word (but don't tell anyone!) * -\***************************************************************************/ +ARMword ARMul_ReLoadInstr(ARMul_State * state, ARMword address, ARMword isize) { + ARMword data; -ARMword -ARMul_ReadWord (ARMul_State * state, ARMword address) -{ - ARMword data; - fault_t fault; - -#ifdef ABORTS - if (address >= LOWABORT && address < HIGHABORT) { - ARMul_DATAABORT (address); - return ARMul_ABORTWORD; - } - else { - ARMul_CLEARABORT; - } -#endif + if ((isize == 2) && (address & 0x2)) { + ARMword lo; + lo = (u16)Memory::Read16(address); + return lo; + } - fault = GetWord (state, address, &data); - if (fault) { - state->mmu.fault_status = - (fault | (state->mmu.last_domain << 4)) & 0xFF; - state->mmu.fault_address = address; - ARMul_DATAABORT (address); - return ARMul_ABORTWORD; - } - else { - ARMul_CLEARABORT; - } - return data; + data = (u32)Memory::Read32(address); + return data; } -/***************************************************************************\ -* Load Word, Sequential Cycle * -\***************************************************************************/ - -ARMword -ARMul_LoadWordS (ARMul_State * state, ARMword address) -{ - state->NumScycles++; - - return ARMul_ReadWord (state, address); +ARMword ARMul_ReadWord(ARMul_State * state, ARMword address) { + ARMword data; + data = Memory::Read32(address); + return data; } -/***************************************************************************\ -* Load Word, Non Sequential Cycle * -\***************************************************************************/ - -ARMword -ARMul_LoadWordN (ARMul_State * state, ARMword address) -{ - state->NumNcycles++; - - return ARMul_ReadWord (state, address); +ARMword ARMul_LoadWordS(ARMul_State * state, ARMword address) { + state->NumScycles++; + return ARMul_ReadWord(state, address); } -/***************************************************************************\ -* Load Halfword, (Non Sequential Cycle) * -\***************************************************************************/ - -ARMword -ARMul_LoadHalfWord (ARMul_State * state, ARMword address) -{ - ARMword data; - fault_t fault; - - state->NumNcycles++; - fault = GetHalfWord (state, address, &data); - - if (fault) { - state->mmu.fault_status = - (fault | (state->mmu.last_domain << 4)) & 0xFF; - state->mmu.fault_address = address; - ARMul_DATAABORT (address); - return ARMul_ABORTWORD; - } - else { - ARMul_CLEARABORT; - } - - return data; - +ARMword ARMul_LoadWordN(ARMul_State * state, ARMword address) { + state->NumNcycles++; + return ARMul_ReadWord(state, address); } -/***************************************************************************\ -* Read Byte (but don't tell anyone!) * -\***************************************************************************/ -int ARMul_ICE_ReadByte(ARMul_State * state, ARMword address, ARMword *presult) -{ - ARMword data; - fault_t fault; - fault = GetByte (state, address, &data); - if (fault) { - *presult=-1; fault=ALIGNMENT_FAULT; return fault; - }else{ - *(char *)presult=(unsigned char)(data & 0xff); fault=NO_FAULT; return fault; - } +ARMword ARMul_LoadHalfWord(ARMul_State * state, ARMword address) { + state->NumNcycles++; + return (u16)Memory::Read16(address);; } - - -ARMword -ARMul_ReadByte (ARMul_State * state, ARMword address) -{ - ARMword data; - fault_t fault; - - fault = GetByte (state, address, &data); - - if (fault) { - state->mmu.fault_status = - (fault | (state->mmu.last_domain << 4)) & 0xFF; - state->mmu.fault_address = address; - ARMul_DATAABORT (address); - return ARMul_ABORTWORD; - } - else { - ARMul_CLEARABORT; - } - - return data; - -} - -/***************************************************************************\ -* Load Byte, (Non Sequential Cycle) * -\***************************************************************************/ - -ARMword -ARMul_LoadByte (ARMul_State * state, ARMword address) -{ - state->NumNcycles++; - - return ARMul_ReadByte (state, address); -} - -/***************************************************************************\ -* Write Word (but don't tell anyone!) * -\***************************************************************************/ - -void -ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data) -{ - fault_t fault; - -#ifdef ABORTS - if (address >= LOWABORT && address < HIGHABORT) { - ARMul_DATAABORT (address); - return; - } - else { - ARMul_CLEARABORT; - } -#endif - fault = PutWord (state, address, data); - if (fault) { - state->mmu.fault_status = - (fault | (state->mmu.last_domain << 4)) & 0xFF; - state->mmu.fault_address = address; - ARMul_DATAABORT (address); - return; - } - else { - ARMul_CLEARABORT; - } +ARMword ARMul_ReadByte(ARMul_State * state, ARMword address) { + return (u8)Memory::Read8(address); } -/***************************************************************************\ -* Store Word, Sequential Cycle * -\***************************************************************************/ - -void -ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data) -{ - state->NumScycles++; - - ARMul_WriteWord (state, address, data); +ARMword ARMul_LoadByte(ARMul_State * state, ARMword address) { + state->NumNcycles++; + return ARMul_ReadByte(state, address); } -/***************************************************************************\ -* Store Word, Non Sequential Cycle * -\***************************************************************************/ - -void -ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data) -{ - state->NumNcycles++; - - ARMul_WriteWord (state, address, data); +void ARMul_StoreHalfWord(ARMul_State * state, ARMword address, ARMword data) { + state->NumNcycles++; + Memory::Write16(address, data); } -/***************************************************************************\ -* Store HalfWord, (Non Sequential Cycle) * -\***************************************************************************/ - -void -ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data) -{ - fault_t fault; - state->NumNcycles++; - fault = PutHalfWord (state, address, data); - if (fault) { - state->mmu.fault_status = - (fault | (state->mmu.last_domain << 4)) & 0xFF; - state->mmu.fault_address = address; - ARMul_DATAABORT (address); - return; - } - else { - ARMul_CLEARABORT; - } +void ARMul_StoreByte(ARMul_State * state, ARMword address, ARMword data) { + state->NumNcycles++; + ARMul_WriteByte(state, address, data); } -//chy 2006-04-15 -int ARMul_ICE_WriteByte (ARMul_State * state, ARMword address, ARMword data) -{ - fault_t fault; - fault = PutByte (state, address, data); - if (fault) - return 1; - else - return 0; -} -/***************************************************************************\ -* Write Byte (but don't tell anyone!) * -\***************************************************************************/ -//chy 2003-07-10, add real write byte fun -void -ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data) -{ - fault_t fault; - fault = PutByte (state, address, data); - if (fault) { - state->mmu.fault_status = - (fault | (state->mmu.last_domain << 4)) & 0xFF; - state->mmu.fault_address = address; - ARMul_DATAABORT (address); - return; - } - else { - ARMul_CLEARABORT; - } +ARMword ARMul_SwapWord(ARMul_State * state, ARMword address, ARMword data) { + ARMword temp; + state->NumNcycles++; + temp = ARMul_ReadWord(state, address); + state->NumNcycles++; + Memory::Write32(address, data); + return temp; } -/***************************************************************************\ -* Store Byte, (Non Sequential Cycle) * -\***************************************************************************/ - -void -ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data) -{ - state->NumNcycles++; - -#ifdef VALIDATE - if (address == TUBE) { - if (data == 4) - state->Emulate = FALSE; - else - (void) putc ((char) data, stderr); /* Write Char */ - return; - } -#endif - - ARMul_WriteByte (state, address, data); +ARMword ARMul_SwapByte(ARMul_State * state, ARMword address, ARMword data) { + ARMword temp; + temp = ARMul_LoadByte(state, address); + Memory::Write8(address, data); + return temp; } -/***************************************************************************\ -* Swap Word, (Two Non Sequential Cycles) * -\***************************************************************************/ - -ARMword -ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data) -{ - ARMword temp; - - state->NumNcycles++; - - temp = ARMul_ReadWord (state, address); - - state->NumNcycles++; - - PutWord (state, address, data); - - return temp; +void ARMul_WriteWord(ARMul_State * state, ARMword address, ARMword data) { + Memory::Write32(address, data); } -/***************************************************************************\ -* Swap Byte, (Two Non Sequential Cycles) * -\***************************************************************************/ - -ARMword -ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data) +void ARMul_WriteByte(ARMul_State * state, ARMword address, ARMword data) { - ARMword temp; - - temp = ARMul_LoadByte (state, address); - ARMul_StoreByte (state, address, data); - - return temp; + Memory::Write8(address, data); } -/***************************************************************************\ -* Count I Cycles * -\***************************************************************************/ - -void -ARMul_Icycles (ARMul_State * state, unsigned number, - ARMword address) +void ARMul_StoreWordS(ARMul_State * state, ARMword address, ARMword data) { - state->NumIcycles += number; - ARMul_CLEARABORT; + state->NumScycles++; + ARMul_WriteWord(state, address, data); } -/***************************************************************************\ -* Count C Cycles * -\***************************************************************************/ - -void -ARMul_Ccycles (ARMul_State * state, unsigned number, - ARMword address) +void ARMul_StoreWordN(ARMul_State * state, ARMword address, ARMword data) { - state->NumCcycles += number; - ARMul_CLEARABORT; + state->NumNcycles++; + ARMul_WriteWord(state, address, data); } diff --git a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp b/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp deleted file mode 100644 index 07951e0e6..000000000 --- a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp +++ /dev/null @@ -1,1132 +0,0 @@ -/* - arm1176jzf_s_mmu.c - ARM920T Memory Management Unit emulation. - Copyright (C) 2003 Skyeye Develop Group - for help please send mail to <skyeye-developer@lists.gro.clinux.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include <assert.h> -#include <string.h> -#include <stdint.h> - -#include "core/mem_map.h" - -#include "core/arm/skyeye_common/skyeye_defs.h" - -#include "core/arm/skyeye_common/armdefs.h" -//#include "bank_defs.h" -#if 0 -#define TLB_SIZE 1024 * 1024 -#define ASID 255 -static uint32_t tlb_entry_array[TLB_SIZE][ASID]; -static inline void invalidate_all_tlb(ARMul_State *state){ - memset(&tlb_entry_array[0], 0xFF, sizeof(uint32_t) * TLB_SIZE * ASID); -} -static inline void invalidate_by_mva(ARMul_State *state, ARMword va){ - memset(&tlb_entry_array[va >> 12][va & 0xFF], 0xFF, sizeof(uint32_t)); - return; -} -static inline void invalidate_by_asid(ARMul_State *state, ARMword asid){ - int i; - for(i = 0; i < TLB_SIZE; i++) - memset(&tlb_entry_array[i][asid & 0xFF], 0xFF, sizeof(uint32_t)); - return; -} - -static uint32_t get_phys_page(ARMul_State* state, ARMword va){ - uint32_t phys_page = tlb_entry_array[va >> 12][state->mmu.context_id & 0xFF]; - //printf("In %s, for va=0x%x, page=0x%x\n", __func__, va, phys_page); - return phys_page; -} - -static inline void insert_tlb(ARMul_State* state, ARMword va, ARMword pa){ - //printf("In %s, insert va=0x%x, pa=0x%x\n", __FUNCTION__, va, pa); - //printf("In %s, insert va=0x%x, va>>12=0x%x, pa=0x%x, pa>>12=0x%x\n", __FUNCTION__, va, va >> 12, pa, pa >> 12); - tlb_entry_array[va >> 12][state->mmu.context_id & 0xFF] = pa >> 12; - - return; -} -#endif -#define BANK0_START 0x50000000 -static void* mem_ptr = NULL; - -static int exclusive_detect(ARMul_State* state, ARMword addr){ - #if 0 - for(int i = 0; i < 128; i++){ - if(state->exclusive_tag_array[i] == addr) - return 0; - } - #endif - if(state->exclusive_tag_array[0] == addr) - return 0; - else - return -1; -} - -static void add_exclusive_addr(ARMul_State* state, ARMword addr){ - #if 0 - for(int i = 0; i < 128; i++){ - if(state->exclusive_tag_array[i] == 0xffffffff){ - state->exclusive_tag_array[i] = addr; - //printf("In %s, add addr 0x%x\n", __func__, addr); - return; - } - } - printf("In %s ,can not monitor the addr, out of array\n", __FUNCTION__); - #endif - state->exclusive_tag_array[0] = addr; - return; -} - -static void remove_exclusive(ARMul_State* state, ARMword addr){ - #if 0 - int i; - for(i = 0; i < 128; i++){ - if(state->exclusive_tag_array[i] == addr){ - state->exclusive_tag_array[i] = 0xffffffff; - //printf("In %s, remove addr 0x%x\n", __func__, addr); - return; - } - } - #endif - state->exclusive_tag_array[0] = 0xFFFFFFFF; -} - -/* This function encodes table 8-2 Interpreting AP bits, - returning non-zero if access is allowed. */ -static int -check_perms (ARMul_State *state, int ap, int read) -{ - int s, r, user; - - s = state->mmu.control & CONTROL_SYSTEM; - r = state->mmu.control & CONTROL_ROM; - /* chy 2006-02-15 , should consider system mode, don't conside 26bit mode */ -// printf("ap is %x, user is %x, s is %x, read is %x\n", ap, user, s, read); -// printf("mode is %x\n", state->Mode); - user = (state->Mode == USER32MODE) || (state->Mode == USER26MODE) || (state->Mode == SYSTEM32MODE); - - switch (ap) { - case 0: - return read && ((s && !user) || r); - case 1: - return !user; - case 2: - return read || !user; - case 3: - return 1; - } - return 0; -} - -#if 0 -fault_t -check_access (ARMul_State *state, ARMword virt_addr, tlb_entry_t *tlb, - int read) -{ - int access; - - state->mmu.last_domain = tlb->domain; - access = (state->mmu.domain_access_control >> (tlb->domain * 2)) & 3; - if ((access == 0) || (access == 2)) { - /* It's unclear from the documentation whether this - should always raise a section domain fault, or if - it should be a page domain fault in the case of an - L1 that describes a page table. In the ARM710T - datasheets, "Figure 8-9: Sequence for checking faults" - seems to indicate the former, while "Table 8-4: Priority - encoding of fault status" gives a value for FS[3210] in - the event of a domain fault for a page. Hmm. */ - return SECTION_DOMAIN_FAULT; - } - if (access == 1) { - /* client access - check perms */ - int subpage, ap; -#if 0 - switch (tlb->mapping) { - /*ks 2004-05-09 - * only for XScale - * Extend Small Page(ESP) Format - * 31-12 bits the base addr of ESP - * 11-10 bits SBZ - * 9-6 bits TEX - * 5-4 bits AP - * 3 bit C - * 2 bit B - * 1-0 bits 11 - * */ - case TLB_ESMALLPAGE: /* xj */ - subpage = 0; - /* printf("TLB_ESMALLPAGE virt_addr=0x%x \n",virt_addr ); */ - break; - - case TLB_TINYPAGE: - subpage = 0; - /* printf("TLB_TINYPAGE virt_addr=0x%x \n",virt_addr ); */ - break; - - case TLB_SMALLPAGE: - subpage = (virt_addr >> 10) & 3; - break; - case TLB_LARGEPAGE: - subpage = (virt_addr >> 14) & 3; - break; - case TLB_SECTION: - subpage = 3; - break; - default: - assert (0); - subpage = 0; /* cleans a warning */ - } - ap = (tlb->perms >> (subpage * 2 + 4)) & 3; - if (!check_perms (state, ap, read)) { - if (tlb->mapping == TLB_SECTION) { - return SECTION_PERMISSION_FAULT; - } else { - return SUBPAGE_PERMISSION_FAULT; - } - } -#endif - } else { /* access == 3 */ - /* manager access - don't check perms */ - } - return NO_FAULT; -} -#endif - -#if 0 -fault_t -mmu_translate (ARMul_State *state, ARMword virt_addr, ARMword *phys_addr) -#endif - -/* ap: AP bits value. - * sop: section or page description 0:section 1:page - */ -fault_t -mmu_translate (ARMul_State *state, ARMword virt_addr, ARMword *phys_addr, int *ap, int *sop) -{ - { - /* walk the translation tables */ - ARMword l1addr, l1desc; - if (state->mmu.translation_table_ctrl && virt_addr << state->mmu.translation_table_ctrl >> (32 - state->mmu.translation_table_ctrl - 1)) { - l1addr = state->mmu.translation_table_base1; - l1addr = (((l1addr >> 14) << 14) | (virt_addr >> 18)) & ~3; - } else { - l1addr = state->mmu.translation_table_base0; - l1addr = (((l1addr >> (14 - state->mmu.translation_table_ctrl)) << (14 - state->mmu.translation_table_ctrl)) | (virt_addr << state->mmu.translation_table_ctrl) >> (18 + state->mmu.translation_table_ctrl)) & ~3; - } - - /* l1desc = mem_read_word (state, l1addr); */ - if (state->space.conf_obj != NULL) - state->space.read(state->space.conf_obj, l1addr, &l1desc, 4); - else - l1desc = Memory::Read32(l1addr); //mem_read_raw(32, l1addr, &l1desc); - - #if 0 - if (virt_addr == 0xc000d2bc) { - printf("mmu_control is %x\n", state->mmu.translation_table_ctrl); - printf("mmu_table_0 is %x\n", state->mmu.translation_table_base0); - printf("mmu_table_1 is %x\n", state->mmu.translation_table_base1); - printf("l1addr is %x l1desc is %x\n", l1addr, l1desc); - // exit(-1); - } - #endif - switch (l1desc & 3) { - case 0: - case 3: - /* - * according to Figure 3-9 Sequence for checking faults in arm manual, - * section translation fault should be returned here. - */ - { - return SECTION_TRANSLATION_FAULT; - } - case 1: - /* coarse page table */ - { - ARMword l2addr, l2desc; - - - l2addr = l1desc & 0xFFFFFC00; - l2addr = (l2addr | - ((virt_addr & 0x000FF000) >> 10)) & - ~3; - if(state->space.conf_obj != NULL) - state->space.read(state->space.conf_obj, l2addr, &l2desc, 4); - else - l2desc = Memory::Read32(l2addr); //mem_read_raw(32, l2addr, &l2desc); - - /* chy 2003-09-02 for xscale */ - *ap = (l2desc >> 4) & 0x3; - *sop = 1; /* page */ - - switch (l2desc & 3) { - case 0: - return PAGE_TRANSLATION_FAULT; - break; - case 1: - *phys_addr = (l2desc & 0xFFFF0000) | (virt_addr & 0x0000FFFF); - break; - case 2: - case 3: - *phys_addr = (l2desc & 0xFFFFF000) | (virt_addr & 0x00000FFF); - break; - - } - } - break; - case 2: - /* section */ - - *ap = (l1desc >> 10) & 3; - *sop = 0; /* section */ - #if 0 - if (virt_addr == 0xc000d2bc) { - printf("mmu_control is %x\n", state->mmu.translation_table_ctrl); - printf("mmu_table_0 is %x\n", state->mmu.translation_table_base0); - printf("mmu_table_1 is %x\n", state->mmu.translation_table_base1); - printf("l1addr is %x l1desc is %x\n", l1addr, l1desc); -// printf("l2addr is %x l2desc is %x\n", l2addr, l2desc); - printf("ap is %x, sop is %x\n", *ap, *sop); - printf("mode is %d\n", state->Mode); -// exit(-1); - } - #endif - - if (l1desc & 0x30000) - *phys_addr = (l1desc & 0xFF000000) | (virt_addr & 0x00FFFFFF); - else - *phys_addr = (l1desc & 0xFFF00000) | (virt_addr & 0x000FFFFF); - break; - } - } - return NO_FAULT; -} - - -static fault_t arm1176jzf_s_mmu_write (ARMul_State *state, ARMword va, - ARMword data, ARMword datatype); -static fault_t arm1176jzf_s_mmu_read (ARMul_State *state, ARMword va, - ARMword *data, ARMword datatype); - -int -arm1176jzf_s_mmu_init (ARMul_State *state) -{ - state->mmu.control = 0x50078; - state->mmu.translation_table_base = 0xDEADC0DE; - state->mmu.domain_access_control = 0xDEADC0DE; - state->mmu.fault_status = 0; - state->mmu.fault_address = 0; - state->mmu.process_id = 0; - state->mmu.context_id = 0; - state->mmu.thread_uro_id = 0; - //invalidate_all_tlb(state); - - return No_exp; -} - -void -arm1176jzf_s_mmu_exit (ARMul_State *state) -{ -} - - -static fault_t -arm1176jzf_s_mmu_load_instr (ARMul_State *state, ARMword va, ARMword *instr) -{ - fault_t fault; - int c; /* cache bit */ - ARMword pa; /* physical addr */ - ARMword perm; /* physical addr access permissions */ - int ap, sop; - - static int debug_count = 0; /* used for debug */ - - //DEBUG_LOG(ARM11, "va = %x\n", va); - - va = mmu_pid_va_map (va); - if (MMU_Enabled) { -// printf("MMU enabled.\n"); -// sleep(1); - /* align check */ - if ((va & (WORD_SIZE - 1)) && MMU_Aligned) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } else - va &= ~(WORD_SIZE - 1); - - /* translate tlb */ - fault = mmu_translate (state, va, &pa, &ap, &sop); - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - printf("va=0x%x, icounter=%lld, fault=%d\n", va, state->NumInstrs, fault); - return fault; - } - - - /* no tlb, only check permission */ - if (!check_perms(state, ap, 1)) { - if (sop == 0) { - return SECTION_PERMISSION_FAULT; - } else { - return SUBPAGE_PERMISSION_FAULT; - } - } - -#if 0 - /*check access */ - fault = check_access (state, va, tlb, 1); - if (fault) { - DEBUG_LOG(ARM11, "check_fault\n"); - return fault; - } -#endif - } - - /*if MMU disabled or C flag is set alloc cache */ - if (MMU_Disabled) { -// printf("MMU disabled.\n"); -// sleep(1); - pa = va; - } - if(state->space.conf_obj == NULL) - state->space.read(state->space.conf_obj, pa, instr, 4); - else - *instr = Memory::Read32(pa); //mem_read_raw(32, pa, instr); - - return NO_FAULT; -} - -static fault_t -arm1176jzf_s_mmu_read_byte (ARMul_State *state, ARMword virt_addr, ARMword *data) -{ - /* ARMword temp,offset; */ - fault_t fault; - fault = arm1176jzf_s_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE); - return fault; -} - -static fault_t -arm1176jzf_s_mmu_read_halfword (ARMul_State *state, ARMword virt_addr, - ARMword *data) -{ - /* ARMword temp,offset; */ - fault_t fault; - fault = arm1176jzf_s_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE); - return fault; -} - -static fault_t -arm1176jzf_s_mmu_read_word (ARMul_State *state, ARMword virt_addr, ARMword *data) -{ - return arm1176jzf_s_mmu_read (state, virt_addr, data, ARM_WORD_TYPE); -} - -static fault_t -arm1176jzf_s_mmu_read (ARMul_State *state, ARMword va, ARMword *data, - ARMword datatype) -{ - fault_t fault; - ARMword pa, real_va, temp, offset; - ARMword perm; /* physical addr access permissions */ - int ap, sop; - - //DEBUG_LOG(ARM11, "va = %x\n", va); - - va = mmu_pid_va_map (va); - real_va = va; - /* if MMU disabled, memory_read */ - if (MMU_Disabled) { -// printf("MMU disabled cpu_id:%x addr:%x.\n", state->mmu.process_id, va); -// sleep(1); - - /* *data = mem_read_word(state, va); */ - if (datatype == ARM_BYTE_TYPE) - /* *data = mem_read_byte (state, va); */ - if(state->space.conf_obj != NULL) - state->space.read(state->space.conf_obj, va, data, 1); - else - *data = Memory::Read8(va); //mem_read_raw(8, va, data); - else if (datatype == ARM_HALFWORD_TYPE) - /* *data = mem_read_halfword (state, va); */ - if(state->space.conf_obj != NULL) - state->space.read(state->space.conf_obj, va, data, 2); - else - *data = Memory::Read16(va); //mem_read_raw(16, va, data); - else if (datatype == ARM_WORD_TYPE) - /* *data = mem_read_word (state, va); */ - if(state->space.conf_obj != NULL) - state->space.read(state->space.conf_obj, va, data, 4); - else - *data = Memory::Read32(va); //mem_read_raw(32, va, data); - else { - ERROR_LOG(ARM11, "SKYEYE:1 arm1176jzf_s_mmu_read error: unknown data type %d\n", datatype); - } - - return NO_FAULT; - } -// printf("MMU enabled.\n"); -// sleep(1); - - /* align check */ - if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) || - ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } - - /* va &= ~(WORD_SIZE - 1); */ - #if 0 - uint32_t page_base; - page_base = get_phys_page(state, va); - if((page_base & 0xFFF) == 0){ - pa = (page_base << 12) | (va & 0xFFF); - goto skip_translation; - } - #endif - /*translate va to tlb */ -#if 0 - fault = mmu_translate (state, va, ARM920T_D_TLB (), &tlb); -#endif - fault = mmu_translate (state, va, &pa, &ap, &sop); -#if 0 - if(va ==0xbebb1774 || state->Reg[15] == 0x400ff594){ - //printf("In %s, current=0x%x. mode is %x, pc=0x%x\n", __FUNCTION__, state->CurrInstr, state->Mode, state->Reg[15]); - printf("In %s, ap is %d, sop is %d, va=0x%x, pa=0x%x, fault=%d, data=0x%x\n", __FUNCTION__, ap, sop, va, pa, fault, data); - int i; - for(i = 0; i < 16; i++) - printf("Reg[%d]=0x%x\t", i, state->Reg[i]); - printf("\n"); - } -#endif - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - //printf("mmu read fault at %x\n", va); - //printf("fault is %d\n", fault); - return fault; - } -// printf("va is %x pa is %x\n", va, pa); - - /* no tlb, only check permission */ - if (!check_perms(state, ap, 1)) { - if (sop == 0) { - return SECTION_PERMISSION_FAULT; - } else { - return SUBPAGE_PERMISSION_FAULT; - } - } -#if 0 - /*check access permission */ - fault = check_access (state, va, tlb, 1); - if (fault) - return fault; -#endif - - //insert_tlb(state, va, pa); -skip_translation: - /* *data = mem_read_word(state, pa); */ - if (datatype == ARM_BYTE_TYPE) { - /* *data = mem_read_byte (state, pa | (real_va & 3)); */ - if(state->space.conf_obj != NULL) - state->space.read(state->space.conf_obj, pa | (real_va & 3), data, 1); - else - *data = Memory::Read8(pa | (real_va & 3)); //mem_read_raw(8, pa | (real_va & 3), data); - /* mem_read_raw(32, pa | (real_va & 3), data); */ - } else if (datatype == ARM_HALFWORD_TYPE) { - /* *data = mem_read_halfword (state, pa | (real_va & 2)); */ - if(state->space.conf_obj != NULL) - state->space.read(state->space.conf_obj, pa | (real_va & 3), data, 2); - else - *data = Memory::Read16(pa | (real_va & 3)); //mem_read_raw(16, pa | (real_va & 3), data); - /* mem_read_raw(32, pa | (real_va & 2), data); */ - } else if (datatype == ARM_WORD_TYPE) - /* *data = mem_read_word (state, pa); */ - if(state->space.conf_obj != NULL) - state->space.read(state->space.conf_obj, pa , data, 4); - else - *data = Memory::Read32(pa); //mem_read_raw(32, pa, data); - else { - ERROR_LOG(ARM11, "SKYEYE:2 arm1176jzf_s_mmu_read error: unknown data type %d\n", datatype); - } - if(0 && (va == 0x2869c)){ - printf("In %s, pa is %x va=0x%x, value is %x pc %x, instr=0x%x\n", __FUNCTION__, pa, va, *data, state->Reg[15], state->CurrInstr); - } - - /* ldrex or ldrexb */ - if(((state->CurrInstr & 0x0FF000F0) == 0x01900090) || - ((state->CurrInstr & 0x0FF000F0) == 0x01d00090)){ - int rn = (state->CurrInstr & 0xF0000) >> 16; - if(state->Reg[rn] == va){ - add_exclusive_addr(state, pa | (real_va & 3)); - state->exclusive_access_state = 1; - } - } -#if 0 - if (state->pc == 0xc011a868) { - printf("pa is %x value is %x size is %x\n", pa, data, datatype); - printf("icounter is %lld\n", state->NumInstrs); -// exit(-1); - } -#endif - - return NO_FAULT; -} - - -static fault_t -arm1176jzf_s_mmu_write_byte (ARMul_State *state, ARMword virt_addr, ARMword data) -{ - return arm1176jzf_s_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE); -} - -static fault_t -arm1176jzf_s_mmu_write_halfword (ARMul_State *state, ARMword virt_addr, - ARMword data) -{ - return arm1176jzf_s_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE); -} - -static fault_t -arm1176jzf_s_mmu_write_word (ARMul_State *state, ARMword virt_addr, ARMword data) -{ - return arm1176jzf_s_mmu_write (state, virt_addr, data, ARM_WORD_TYPE); -} - - - -static fault_t -arm1176jzf_s_mmu_write (ARMul_State *state, ARMword va, ARMword data, - ARMword datatype) -{ - int b; - ARMword pa, real_va; - ARMword perm; /* physical addr access permissions */ - fault_t fault; - int ap, sop; - -#if 0 - /8 for sky_printk debugger.*/ - if (va == 0xffffffff) { - putchar((char)data); - return 0; - } - if (va == 0xBfffffff) { - putchar((char)data); - return 0; - } -#endif - - //DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data); - va = mmu_pid_va_map (va); - real_va = va; - - if (MMU_Disabled) { - /* mem_write_word(state, va, data); */ - if (datatype == ARM_BYTE_TYPE) - /* mem_write_byte (state, va, data); */ - if(state->space.conf_obj != NULL) - state->space.write(state->space.conf_obj, va, &data, 1); - else - Memory::Write8(va, data); - else if (datatype == ARM_HALFWORD_TYPE) - /* mem_write_halfword (state, va, data); */ - if(state->space.conf_obj != NULL) - state->space.write(state->space.conf_obj, va, &data, 2); - else - Memory::Write16(va, data); - else if (datatype == ARM_WORD_TYPE) - /* mem_write_word (state, va, data); */ - if(state->space.conf_obj != NULL) - state->space.write(state->space.conf_obj, va, &data, 4); - else - Memory::Write32(va, data); - else { - ERROR_LOG (ARM11, "SKYEYE:1 arm1176jzf_s_mmu_write error: unknown data type %d\n", datatype); - } - goto finished_write; - //return 0; - } - /*align check */ - /* if ((va & (WORD_SIZE - 1)) && MMU_Aligned){ */ - if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) || - ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } - va &= ~(WORD_SIZE - 1); - #if 0 - uint32_t page_base; - page_base = get_phys_page(state, va); - if((page_base & 0xFFF) == 0){ - pa = (page_base << 12) | (va & 0xFFF); - goto skip_translation; - } - #endif - /*tlb translate */ - fault = mmu_translate (state, va, &pa, &ap, &sop); -#if 0 - if(va ==0xbebb1774 || state->Reg[15] == 0x40102334){ - //printf("In %s, current=0x%x. mode is %x, pc=0x%x\n", __FUNCTION__, state->CurrInstr, state->Mode, state->Reg[15]); - printf("In %s, ap is %d, sop is %d, va=0x%x, pa=0x%x, fault=%d, data=0x%x\n", __FUNCTION__, ap, sop, va, pa, fault, data); - int i; - for(i = 0; i < 16; i++) - printf("Reg[%d]=0x%x\t", i, state->Reg[i]); - printf("\n"); - } -#endif - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - //printf("mmu write fault at %x\n", va); - return fault; - } -// printf("va is %x pa is %x\n", va, pa); - - /* no tlb, only check permission */ - if (!check_perms(state, ap, 0)) { - if (sop == 0) { - return SECTION_PERMISSION_FAULT; - } else { - return SUBPAGE_PERMISSION_FAULT; - } - } - -#if 0 - /* tlb check access */ - fault = check_access (state, va, tlb, 0); - if (fault) { - DEBUG_LOG(ARM11, "check_access\n"); - return fault; - } -#endif -#if 0 - if (pa <= 0x502860ff && (pa + 1 << datatype) > 0x502860ff) { - printf("pa is %x value is %x size is %x\n", pa, data, datatype); - } -#endif -#if 0 - if (state->pc == 0xc011a878) { - printf("write pa is %x value is %x size is %x\n", pa, data, datatype); - printf("icounter is %lld\n", state->NumInstrs); - exit(-1); - } -#endif - //insert_tlb(state, va, pa); -skip_translation: - /* strex */ - if(((state->CurrInstr & 0x0FF000F0) == 0x01800090) || - ((state->CurrInstr & 0x0FF000F0) == 0x01c00090)){ - /* failed , the address is monitord now. */ - int dest_reg = (state->CurrInstr & 0xF000) >> 12; - if((exclusive_detect(state, pa | (real_va & 3)) == 0) && (state->exclusive_access_state == 1)){ - remove_exclusive(state, pa | (real_va & 3)); - state->Reg[dest_reg] = 0; - state->exclusive_access_state = 0; - } - else{ - state->Reg[dest_reg] = 1; - //printf("In %s, try to strex a monitored address 0x%x\n", __FUNCTION__, pa); - return NO_FAULT; - } - } - - if (datatype == ARM_BYTE_TYPE) { - /* mem_write_byte (state, - (pa | (real_va & 3)), - data); - */ - if(state->space.conf_obj != NULL) - state->space.write(state->space.conf_obj, (pa | (real_va & 3)), &data, 1); - else - Memory::Write8((pa | (real_va & 3)), data); - - } else if (datatype == ARM_HALFWORD_TYPE) - /* mem_write_halfword (state, - (pa | - (real_va & 2)), - data); - */ - if(state->space.conf_obj != NULL) - state->space.write(state->space.conf_obj, (pa | (real_va & 3)), &data, 2); - else - Memory::Write16((pa | (real_va & 3)), data); - else if (datatype == ARM_WORD_TYPE) - /* mem_write_word (state, pa, data); */ - if(state->space.conf_obj != NULL) - state->space.write(state->space.conf_obj, pa, &data, 4); - else - Memory::Write32(pa, data); -#if 0 - if (state->NumInstrs > 236403) { - printf("write memory\n"); - printf("pa is %x value is %x size is %x\n", pa, data, datatype); - printf("icounter is %lld\n", state->NumInstrs); - } -#endif -finished_write: -#if DIFF_WRITE - if(state->icounter > state->debug_icounter){ - if(state->CurrWrite >= 17 ){ - printf("Wrong write array, 0x%x", state->CurrWrite); - exit(-1); - } - uint32 record_data = data; - if(datatype == ARM_BYTE_TYPE) - record_data &= 0xFF; - if(datatype == ARM_HALFWORD_TYPE) - record_data &= 0xFFFF; - - state->WriteAddr[state->CurrWrite] = pa | (real_va & 3); - state->WriteData[state->CurrWrite] = record_data; - state->WritePc[state->CurrWrite] = state->Reg[15]; - state->CurrWrite++; - //printf("In %s, pc=0x%x, addr=0x%x, data=0x%x, CFlag=%d\n", __FUNCTION__, state->Reg[15], pa | (real_va & 3), record_data, state->CFlag); - } -#endif - - return NO_FAULT; -} - -ARMword -arm1176jzf_s_mmu_mrc (ARMul_State *state, ARMword instr, ARMword *value) -{ - int creg = BITS (16, 19) & 0xf; - int OPC_1 = BITS (21, 23) & 0x7; - int OPC_2 = BITS (5, 7) & 0x7; - ARMword data; - - switch (creg) { - case MMU_ID: - if (OPC_2 == 0) { - data = state->cpu->cpu_val; - } else if (OPC_2 == 1) { - /* Cache type: - * 000 0110 1 000 101 110 0 10 000 101 110 0 10 - * */ - data = 0x0D172172; - } - break; - case MMU_CONTROL: - /* - * 6:3 read as 1 - * 10 read as 0 - * 18,16 read as 1 - * */ - data = (state->mmu.control | 0x50078) & 0xFFFFFBFF; - break; - case MMU_TRANSLATION_TABLE_BASE: -#if 0 - data = state->mmu.translation_table_base; -#endif - switch (OPC_2) { - case 0: - data = state->mmu.translation_table_base0; - break; - case 1: - data = state->mmu.translation_table_base1; - break; - case 2: - data = state->mmu.translation_table_ctrl; - break; - default: - printf ("mmu_mrc read UNKNOWN - p15 c2 opcode2 %d\n", OPC_2); - break; - } - break; - case MMU_DOMAIN_ACCESS_CONTROL: - data = state->mmu.domain_access_control; - break; - case MMU_FAULT_STATUS: - /* OPC_2 = 0: data FSR value - * */ - if (OPC_2 == 0) - data = state->mmu.fault_status; - if (OPC_2 == 1) - data = state->mmu.fault_statusi; - break; - case MMU_FAULT_ADDRESS: - data = state->mmu.fault_address; - break; - case MMU_PID: - //data = state->mmu.process_id; - if(OPC_2 == 0) - data = state->mmu.process_id; - else if(OPC_2 == 1) - data = state->mmu.context_id; - else if(OPC_2 == 3){ - data = state->mmu.thread_uro_id; - } - else{ - printf ("mmu_mcr read UNKNOWN - reg %d\n", creg); - } - //printf("SKYEYE In %s, read pid 0x%x, OPC_2 %d, instr=0x%x\n", __FUNCTION__, data, OPC_2, instr); - //exit(-1); - break; - default: - printf ("mmu_mrc read UNKNOWN - reg %d\n", creg); - data = 0; - break; - } -/* printf("\t\t\t\t\tpc = 0x%08x\n", state->Reg[15]); */ - *value = data; - return data; -} - - -static ARMword -arm1176jzf_s_mmu_mcr (ARMul_State *state, ARMword instr, ARMword value) -{ - int creg = BITS (16, 19) & 0xf; - int CRm = BITS (0, 3) & 0xf; - int OPC_1 = BITS (21, 23) & 0x7; - int OPC_2 = BITS (5, 7) & 0x7; - if (!strncmp (state->cpu->cpu_arch_name, "armv6", 5)) { - switch (creg) { - case MMU_CONTROL: - /* - * 6:3 read as 1 - * 10 read as 0 - * 18,16 read as 1 - * */ - if(OPC_2 == 0) - state->mmu.control = (value | 0x50078) & 0xFFFFFBFF; - else if(OPC_2 == 1) - state->mmu.auxiliary_control = value; - else if(OPC_2 == 2) - state->mmu.coprocessor_access_control = value; - else - fprintf(stderr, "In %s, wrong OPC_2 %d\n", __FUNCTION__, OPC_2); - break; - case MMU_TRANSLATION_TABLE_BASE: - switch (OPC_2) { - /* int i; */ - case 0: -#if 0 - /* TTBR0 */ - if (state->mmu.translation_table_ctrl & 0x7) { - for (i = 0; i <= state->mmu.translation_table_ctrl; i++) - state->mmu.translation_table_base0 &= ~(1 << (5 + i)); - } -#endif - state->mmu.translation_table_base0 = (value); - break; - case 1: -#if 0 - /* TTBR1 */ - if (state->mmu.translation_table_ctrl & 0x7) { - for (i = 0; i <= state->mmu.translation_table_ctrl; i++) - state->mmu.translation_table_base1 &= 1 << (5 + i); - } -#endif - state->mmu.translation_table_base1 = (value); - break; - case 2: - /* TTBC */ - state->mmu.translation_table_ctrl = value & 0x7; - break; - default: - printf ("mmu_mcr wrote UNKNOWN - cp15 c2 opcode2 %d\n", OPC_2); - break; - } - //printf("SKYEYE In %s, write TLB_BASE 0x%x OPC_2=%d instr=0x%x\n", __FUNCTION__, value, OPC_2, instr); - //invalidate_all_tlb(state); - break; - case MMU_DOMAIN_ACCESS_CONTROL: - /* printf("mmu_mcr wrote DACR "); */ - state->mmu.domain_access_control = value; - break; - - case MMU_FAULT_STATUS: - if (OPC_2 == 0) - state->mmu.fault_status = value & 0xFF; - if (OPC_2 == 1) { - printf("set fault status instr\n"); - } - break; - case MMU_FAULT_ADDRESS: - state->mmu.fault_address = value; - break; - - case MMU_CACHE_OPS: - break; - case MMU_TLB_OPS: - { - switch(CRm){ - case 5: /* ITLB */ - { - switch(OPC_2){ - case 0: /* invalidate all */ - //invalidate_all_tlb(state); - break; - case 1: /* invalidate by MVA */ - //invalidate_by_mva(state, value); - break; - case 2: /* invalidate by asid */ - //invalidate_by_asid(state, value); - break; - default: - printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg); - break; - } - break; - } - case 6: /* DTLB */ - { - switch(OPC_2){ - case 0: /* invalidate all */ - //invalidate_all_tlb(state); - break; - case 1: /* invalidate by MVA */ - //invalidate_by_mva(state, value); - break; - case 2: /* invalidate by asid */ - //invalidate_by_asid(state, value); - break; - default: - printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg); - break; - } - break; - } - case 7: /* Unified TLB */ - { - switch(OPC_2){ - case 0: /* invalidate all */ - //invalidate_all_tlb(state); - break; - case 1: /* invalidate by MVA */ - //invalidate_by_mva(state, value); - break; - case 2: /* invalidate by asid */ - //invalidate_by_asid(state, value); - break; - default: - printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg); - break; - } - break; - } - - default: - printf ("mmu_mcr wrote UNKNOWN - reg %d, CRm=%d\n", creg, CRm); - break; - } - //printf("SKYEYE In %s, write TLB 0x%x OPC_1=%d, OPC_2=%d , CRm=%d instr=0x%x\n", __FUNCTION__, value, OPC_1, OPC_2, CRm, instr); - } - break; - case MMU_CACHE_LOCKDOWN: - /* - * FIXME: cache lock down*/ - break; - case MMU_TLB_LOCKDOWN: - printf("SKYEYE In %s, write TLB_LOCKDOWN 0x%x OPC_2=%d instr=0x%x\n", __FUNCTION__, value, OPC_2, instr); - /* FIXME:tlb lock down */ - break; - case MMU_PID: - //printf("SKYEYE In %s, write pid 0x%x OPC_2=%d instr=0x%x\n", __FUNCTION__, value, OPC_2, instr); - //state->mmu.process_id = value; - /*0:24 should be zero. */ - //state->mmu.process_id = value & 0xfe000000; - if(OPC_2 == 0) - state->mmu.process_id = value; - else if(OPC_2 == 1) - state->mmu.context_id = value; - else if(OPC_2 == 3){ - state->mmu.thread_uro_id = value; - } - else{ - printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg); - } - break; - - default: - printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg); - break; - } - } - - return No_exp; -} - -///* teawater add for arm2x86 2005.06.19------------------------------------------- */ -//static int -//arm1176jzf_s_mmu_v2p_dbct (ARMul_State *state, ARMword virt_addr, -// ARMword *phys_addr) -//{ -// fault_t fault; -// int ap, sop; -// -// ARMword perm; /* physical addr access permissions */ -// virt_addr = mmu_pid_va_map (virt_addr); -// if (MMU_Enabled) { -// -// /*align check */ -// if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) { -// DEBUG_LOG(ARM11, "align\n"); -// return ALIGNMENT_FAULT; -// } else -// virt_addr &= ~(WORD_SIZE - 1); -// -// /*translate tlb */ -// fault = mmu_translate (state, virt_addr, phys_addr, &ap, &sop); -// if (fault) { -// DEBUG_LOG(ARM11, "translate\n"); -// return fault; -// } -// -// /* permission check */ -// if (!check_perms(state, ap, 1)) { -// if (sop == 0) { -// return SECTION_PERMISSION_FAULT; -// } else { -// return SUBPAGE_PERMISSION_FAULT; -// } -// } -//#if 0 -// /*check access */ -// fault = check_access (state, virt_addr, tlb, 1); -// if (fault) { -// DEBUG_LOG(ARM11, "check_fault\n"); -// return fault; -// } -//#endif -// } -// -// if (MMU_Disabled) { -// *phys_addr = virt_addr; -// } -// -// return 0; -//} - -/* AJ2D-------------------------------------------------------------------------- */ - -/*arm1176jzf-s mmu_ops_t*/ -mmu_ops_t arm1176jzf_s_mmu_ops = { - arm1176jzf_s_mmu_init, - arm1176jzf_s_mmu_exit, - arm1176jzf_s_mmu_read_byte, - arm1176jzf_s_mmu_write_byte, - arm1176jzf_s_mmu_read_halfword, - arm1176jzf_s_mmu_write_halfword, - arm1176jzf_s_mmu_read_word, - arm1176jzf_s_mmu_write_word, - arm1176jzf_s_mmu_load_instr, - arm1176jzf_s_mmu_mcr, - arm1176jzf_s_mmu_mrc -/* teawater add for arm2x86 2005.06.19------------------------------------------- */ -/* arm1176jzf_s_mmu_v2p_dbct, */ -/* AJ2D-------------------------------------------------------------------------- */ -}; diff --git a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h b/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h deleted file mode 100644 index 299c6b46b..000000000 --- a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - arm1176JZF-S_mmu.h - ARM1176JZF-S Memory Management Unit emulation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef _ARM1176JZF_S_MMU_H_ -#define _ARM1176JZF_S_MMU_H_ - -#if 0 -typedef struct arm1176jzf-s_mmu_s -{ - tlb_t i_tlb; - cache_t i_cache; - - tlb_t d_tlb; - cache_t d_cache; - wb_t wb_t; -} arm1176jzf-s_mmu_t; -#endif -extern mmu_ops_t arm1176jzf_s_mmu_ops; - -ARMword -arm1176jzf_s_mmu_mrc (ARMul_State *state, ARMword instr, ARMword *value); -#endif /*_ARM1176JZF_S_MMU_H_*/ diff --git a/src/core/arm/interpreter/mmu/cache.cpp b/src/core/arm/interpreter/mmu/cache.cpp deleted file mode 100644 index cfbc31f1e..000000000 --- a/src/core/arm/interpreter/mmu/cache.cpp +++ /dev/null @@ -1,370 +0,0 @@ -#include "core/arm/skyeye_common/armdefs.h" - -/* mmu cache init - * - * @cache_t :cache_t to init - * @width :cache line width in byte - * @way :way of each cache set - * @set :cache set num - * - * $ -1: error - * 0: sucess - */ -int -mmu_cache_init (cache_s * cache_t, int width, int way, int set, int w_mode) -{ - int i, j; - cache_set_t *sets; - cache_line_t *lines; - - /*alloc cache set */ - sets = NULL; - lines = NULL; - //fprintf(stderr, "mmu_cache_init: mallloc beg size %d,sets 0x%x\n", sizeof(cache_set_t) * set,sets); - //exit(-1); - sets = (cache_set_t *) malloc (sizeof (cache_set_t) * set); - if (sets == NULL) { - ERROR_LOG(ARM11, "set malloc size %d\n", sizeof (cache_set_t) * set); - goto sets_error; - } - //fprintf(stderr, "mmu_cache_init: mallloc end sets 0x%x\n", sets); - cache_t->sets = sets; - - /*init cache set */ - for (i = 0; i < set; i++) { - /*alloc cache line */ - lines = (cache_line_t *) malloc (sizeof (cache_line_t) * way); - if (lines == NULL) { - ERROR_LOG(ARM11, "line malloc size %d\n", - sizeof (cache_line_t) * way); - goto lines_error; - } - /*init cache line */ - for (j = 0; j < way; j++) { - lines[j].tag = 0; //invalid - lines[j].data = (ARMword *) malloc (width); - if (lines[j].data == NULL) { - ERROR_LOG(ARM11, "data alloc size %d\n", width); - goto data_error; - } - } - - sets[i].lines = lines; - sets[i].cycle = 0; - - } - cache_t->width = width; - cache_t->set = set; - cache_t->way = way; - cache_t->w_mode = w_mode; - return 0; - - data_error: - /*free data */ - while (j-- > 0) - free (lines[j].data); - /*free data error line */ - free (lines); - lines_error: - /*free lines already alloced */ - while (i-- > 0) { - for (j = 0; j < way; j++) - free (sets[i].lines[j].data); - free (sets[i].lines); - } - /*free sets */ - free (sets); - sets_error: - return -1; -}; - -/* free a cache_t's inner data, the ptr self is not freed, - * when needed do like below: - * mmu_cache_exit(cache); - * free(cache_t); - * - * @cache_t : the cache_t to free - */ - -void -mmu_cache_exit (cache_s * cache_t) -{ - int i, j; - cache_set_t *sets, *set; - cache_line_t *lines, *line; - - /*free all set */ - sets = cache_t->sets; - for (set = sets, i = 0; i < cache_t->set; i++, set++) { - /*free all line */ - lines = set->lines; - for (line = lines, j = 0; j < cache_t->way; j++, line++) - free (line->data); - free (lines); - } - free (sets); -} - -/* mmu cache search - * - * @state :ARMul_State - * @cache_t :cache_t to search - * @va :virtual address - * - * $ NULL: no cache match - * cache :cache matched - */ -cache_line_t * -mmu_cache_search (ARMul_State * state, cache_s * cache_t, ARMword va) -{ - int i; - int set = va_cache_set (va, cache_t); - ARMword tag = va_cache_align (va, cache_t); - cache_line_t *cache; - - cache_set_t *cache_set = cache_t->sets + set; - for (i = 0, cache = cache_set->lines; i < cache_t->way; i++, cache++) { - if ((cache->tag & TAG_VALID_FLAG) - && (tag == va_cache_align (cache->tag, cache_t))) - return cache; - } - return NULL; -} - -/* mmu cache search by set/index - * - * @state :ARMul_State - * @cache_t :cache_t to search - * @index :set/index value. - * - * $ NULL: no cache match - * cache :cache matched - */ -cache_line_t * -mmu_cache_search_by_index (ARMul_State * state, cache_s * cache_t, - ARMword index) -{ - int way = cache_t->way; - int set_v = index_cache_set (index, cache_t); - int i = 0, index_v = 0; - cache_set_t *set; - - while ((way >>= 1) >= 1) - i++; - index_v = index >> (32 - i); - set = cache_t->sets + set_v; - - return set->lines + index_v; -} - - -/* mmu cache alloc - * - * @state :ARMul_State - * @cache_t :cache_t to alloc from - * @va :virtual address that require cache alloc, need not cache aligned - * @pa :physical address of va - * - * $ cache_alloced, always alloc OK - */ -cache_line_t * -mmu_cache_alloc (ARMul_State * state, cache_s * cache_t, ARMword va, - ARMword pa) -{ - cache_line_t *cache; - cache_set_t *set; - int i; - - va = va_cache_align (va, cache_t); - pa = va_cache_align (pa, cache_t); - - set = &cache_t->sets[va_cache_set (va, cache_t)]; - - /*robin-round */ - cache = &set->lines[set->cycle++]; - if (set->cycle == cache_t->way) - set->cycle = 0; - - if (cache_t->w_mode == CACHE_WRITE_BACK) { - ARMword t; - - /*if cache valid, try to write back */ - if (cache->tag & TAG_VALID_FLAG) { - mmu_cache_write_back (state, cache_t, cache); - } - /*read in cache_line */ - t = pa; - for (i = 0; i < (cache_t->width >> WORD_SHT); - i++, t += WORD_SIZE) { - //cache->data[i] = mem_read_word (state, t); - bus_read(32, t, &cache->data[i]); - } - } - /*store tag and pa */ - cache->tag = va | TAG_VALID_FLAG; - cache->pa = pa; - - return cache; -}; - -/* mmu_cache_write_back write cache data to memory - * @state - * @cache_t :cache_t of the cache line - * @cache : cache line - */ -void -mmu_cache_write_back (ARMul_State * state, cache_s * cache_t, - cache_line_t * cache) -{ - ARMword pa = cache->pa; - int nw = cache_t->width >> WORD_SHT; - ARMword *data = cache->data; - int i; - int t0, t1, t2; - - if ((cache->tag & 1) == 0) - return; - - switch (cache-> - tag & ~1 & (TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY)) { - case 0: - return; - case TAG_FIRST_HALF_DIRTY: - nw /= 2; - break; - case TAG_LAST_HALF_DIRTY: - nw /= 2; - pa += nw << WORD_SHT; - data += nw; - break; - case TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY: - break; - } - for (i = 0; i < nw; i++, data++, pa += WORD_SIZE) - //mem_write_word (state, pa, *data); - bus_write(32, pa, *data); - - cache->tag &= ~(TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY); -}; - - -/* mmu_cache_clean: clean a cache of va in cache_t - * - * @state :ARMul_State - * @cache_t :cache_t to clean - * @va :virtaul address - */ -void -mmu_cache_clean (ARMul_State * state, cache_s * cache_t, ARMword va) -{ - cache_line_t *cache; - - cache = mmu_cache_search (state, cache_t, va); - if (cache) - mmu_cache_write_back (state, cache_t, cache); -} - -/* mmu_cache_clean_by_index: clean a cache by set/index format value - * - * @state :ARMul_State - * @cache_t :cache_t to clean - * @va :set/index format value - */ -void -mmu_cache_clean_by_index (ARMul_State * state, cache_s * cache_t, - ARMword index) -{ - cache_line_t *cache; - - cache = mmu_cache_search_by_index (state, cache_t, index); - if (cache) - mmu_cache_write_back (state, cache_t, cache); -} - -/* mmu_cache_invalidate : invalidate a cache of va - * - * @state :ARMul_State - * @cache_t :cache_t to invalid - * @va :virt_addr to invalid - */ -void -mmu_cache_invalidate (ARMul_State * state, cache_s * cache_t, ARMword va) -{ - cache_line_t *cache; - - cache = mmu_cache_search (state, cache_t, va); - if (cache) { - mmu_cache_write_back (state, cache_t, cache); - cache->tag = 0; - } -} - -/* mmu_cache_invalidate_by_index : invalidate a cache by index format - * - * @state :ARMul_State - * @cache_t :cache_t to invalid - * @index :set/index data - */ -void -mmu_cache_invalidate_by_index (ARMul_State * state, cache_s * cache_t, - ARMword index) -{ - cache_line_t *cache; - - cache = mmu_cache_search_by_index (state, cache_t, index); - if (cache) { - mmu_cache_write_back (state, cache_t, cache); - cache->tag = 0; - } -} - -/* mmu_cache_invalidate_all - * - * @state: - * @cache_t - * */ -void -mmu_cache_invalidate_all (ARMul_State * state, cache_s * cache_t) -{ - int i, j; - cache_set_t *set; - cache_line_t *cache; - - set = cache_t->sets; - for (i = 0; i < cache_t->set; i++, set++) { - cache = set->lines; - for (j = 0; j < cache_t->way; j++, cache++) { - mmu_cache_write_back (state, cache_t, cache); - cache->tag = 0; - } - } -}; - -void -mmu_cache_soft_flush (ARMul_State * state, cache_s * cache_t, ARMword pa) -{ - ARMword set, way; - cache_line_t *cache; - pa = (pa / cache_t->width); - way = pa & (cache_t->way - 1); - set = (pa / cache_t->way) & (cache_t->set - 1); - cache = &cache_t->sets[set].lines[way]; - - mmu_cache_write_back (state, cache_t, cache); - cache->tag = 0; -} - -cache_line_t* mmu_cache_dirty_cache(ARMul_State *state,cache_s *cache){ - int i; - int j; - cache_line_t *cache_line = NULL; - cache_set_t *cache_set = cache->sets; - int sets = cache->set; - for (i = 0; i < sets; i++){ - for(j = 0,cache_line = &cache_set[i].lines[0]; j < cache->way; j++,cache_line++){ - if((cache_line->tag & TAG_FIRST_HALF_DIRTY) || (cache_line->tag & TAG_LAST_HALF_DIRTY)) - return cache_line; - } - } - return NULL; -} diff --git a/src/core/arm/interpreter/mmu/cache.h b/src/core/arm/interpreter/mmu/cache.h deleted file mode 100644 index d308d9b87..000000000 --- a/src/core/arm/interpreter/mmu/cache.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef _MMU_CACHE_H_ -#define _MMU_CACHE_H_ - -typedef struct cache_line_t -{ - ARMword tag; /* cache line align address | - bit2: last half dirty - bit1: first half dirty - bit0: cache valid flag - */ - ARMword pa; /*physical address */ - ARMword *data; /*array of cached data */ -} cache_line_t; -#define TAG_VALID_FLAG 0x00000001 -#define TAG_FIRST_HALF_DIRTY 0x00000002 -#define TAG_LAST_HALF_DIRTY 0x00000004 - -/*cache set association*/ -typedef struct cache_set_s -{ - cache_line_t *lines; - int cycle; -} cache_set_t; - -enum -{ - CACHE_WRITE_BACK, - CACHE_WRITE_THROUGH, -}; - -typedef struct cache_s -{ - int width; /*bytes in a line */ - int way; /*way of set asscociate */ - int set; /*num of set */ - int w_mode; /*write back or write through */ - //int a_mode; /*alloc mode: random or round-bin*/ - cache_set_t *sets; - /**/} cache_s; - -typedef struct cache_desc_s -{ - int width; - int way; - int set; - int w_mode; -// int a_mode; -} cache_desc_t; - - -/*virtual address to cache set index*/ -#define va_cache_set(va, cache_t) \ - (((va) / (cache_t)->width) & ((cache_t)->set - 1)) -/*virtual address to cahce line aligned*/ -#define va_cache_align(va, cache_t) \ - ((va) & ~((cache_t)->width - 1)) -/*virtaul address to cache line word index*/ -#define va_cache_index(va, cache_t) \ - (((va) & ((cache_t)->width - 1)) >> WORD_SHT) - -/*see Page 558 in arm manual*/ -/*set/index format value to cache set value*/ -#define index_cache_set(index, cache_t) \ - (((index) / (cache_t)->width) & ((cache_t)->set - 1)) - -/*************************cache********************/ -/* mmu cache init - * - * @cache_t :cache_t to init - * @width :cache line width in byte - * @way :way of each cache set - * @set :cache set num - * @w_mode :cache w_mode - * - * $ -1: error - * 0: sucess - */ -int -mmu_cache_init (cache_s * cache_t, int width, int way, int set, int w_mode); - -/* free a cache_t's inner data, the ptr self is not freed, - * when needed do like below: - * mmu_cache_exit(cache); - * free(cache_t); - * - * @cache_t : the cache_t to free - */ -void mmu_cache_exit (cache_s * cache_t); - -/* mmu cache search - * - * @state :ARMul_State - * @cache_t :cache_t to search - * @va :virtual address - * - * $ NULL: no cache match - * cache :cache matched - * */ -cache_line_t *mmu_cache_search (ARMul_State * state, cache_s * cache_t, - ARMword va); - -/* mmu cache search by set/index - * - * @state :ARMul_State - * @cache_t :cache_t to search - * @index :set/index value. - * - * $ NULL: no cache match - * cache :cache matched - * */ - -cache_line_t *mmu_cache_search_by_index (ARMul_State * state, - cache_s * cache_t, ARMword index); - -/* mmu cache alloc - * - * @state :ARMul_State - * @cache_t :cache_t to alloc from - * @va :virtual address that require cache alloc, need not cache aligned - * @pa :physical address of va - * - * $ cache_alloced, always alloc OK - */ -cache_line_t *mmu_cache_alloc (ARMul_State * state, cache_s * cache_t, - ARMword va, ARMword pa); - -/* mmu_cache_write_back write cache data to memory - * - * @state: - * @cache_t :cache_t of the cache line - * @cache : cache line - */ -void -mmu_cache_write_back (ARMul_State * state, cache_s * cache_t, - cache_line_t * cache); - -/* mmu_cache_clean: clean a cache of va in cache_t - * - * @state :ARMul_State - * @cache_t :cache_t to clean - * @va :virtaul address - */ -void mmu_cache_clean (ARMul_State * state, cache_s * cache_t, ARMword va); -void -mmu_cache_clean_by_index (ARMul_State * state, cache_s * cache_t, - ARMword index); - -/* mmu_cache_invalidate : invalidate a cache of va - * - * @state :ARMul_State - * @cache_t :cache_t to invalid - * @va :virt_addr to invalid - */ -void -mmu_cache_invalidate (ARMul_State * state, cache_s * cache_t, ARMword va); - -void -mmu_cache_invalidate_by_index (ARMul_State * state, cache_s * cache_t, - ARMword index); - -void mmu_cache_invalidate_all (ARMul_State * state, cache_s * cache_t); - -void -mmu_cache_soft_flush (ARMul_State * state, cache_s * cache_t, ARMword pa); - -cache_line_t* mmu_cache_dirty_cache(ARMul_State * state, cache_s * cache_t); - -#endif /*_MMU_CACHE_H_*/ diff --git a/src/core/arm/interpreter/mmu/maverick.cpp b/src/core/arm/interpreter/mmu/maverick.cpp deleted file mode 100644 index a07d4742b..000000000 --- a/src/core/arm/interpreter/mmu/maverick.cpp +++ /dev/null @@ -1,1206 +0,0 @@ -/* maverick.c -- Cirrus/DSP co-processor interface. - Copyright (C) 2003 Free Software Foundation, Inc. - Contributed by Aldy Hernandez (aldyh@redhat.com). - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include <assert.h> - -#include "core/arm/skyeye_common/armdefs.h" -#include "core/arm/skyeye_common/armemu.h" - - -/*#define CIRRUS_DEBUG 1 */ -#if CIRRUS_DEBUG -# define printfdbg printf -#else -# define printfdbg printf_nothing -#endif - -#define POS64(i) ( (~(i)) >> 63 ) -#define NEG64(i) ( (i) >> 63 ) - -/* Define Co-Processor instruction handlers here. */ - -/* Here's ARMulator's DSP definition. A few things to note: - 1) it has 16 64-bit registers and 4 72-bit accumulators - 2) you can only access its registers with MCR and MRC. */ - -/* We can't define these in here because this file might not be linked - unless the target is arm9e-*. They are defined in wrapper.c. - Eventually the simulator should be made to handle any coprocessor - at run time. */ -struct maverick_regs -{ - union - { - int i; - float f; - } upper; - - union - { - int i; - float f; - } lower; -}; - -union maverick_acc_regs -{ - long double ld; /* Acc registers are 72-bits. */ -}; - -struct maverick_regs DSPregs[16]; -union maverick_acc_regs DSPacc[4]; -ARMword DSPsc; - -#define DEST_REG (BITS (12, 15)) -#define SRC1_REG (BITS (16, 19)) -#define SRC2_REG (BITS (0, 3)) - -static int lsw_int_index, msw_int_index; -static int lsw_float_index, msw_float_index; - -static double mv_getRegDouble (int); -static long long mv_getReg64int (int); -static void mv_setRegDouble (int, double val); -static void mv_setReg64int (int, long long val); - -static union -{ - double d; - long long ll; - int ints[2]; -} reg_conv; - -static void -printf_nothing (const char *foo, ...) -{ -} - -static void -cirrus_not_implemented (const char *insn) -{ - fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn); - fprintf (stderr, "aborting!\n"); - - // skyeye_exit (1); -} - -static unsigned -DSPInit (ARMul_State * state) -{ - NOTICE_LOG(ARM11, "ARMul_ConsolePrint: DSP present"); - return TRUE; -} - -unsigned -DSPMRC4 (ARMul_State * state, - unsigned type, ARMword instr, ARMword * value) -{ - switch (BITS (5, 7)) { - case 0: /* cfmvrdl */ - /* Move lower half of a DF stored in a DSP reg into an Arm reg. */ - printfdbg ("cfmvrdl\n"); - printfdbg ("\tlower half=0x%x\n", DSPregs[SRC1_REG].lower.i); - printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG)); - - *value = (ARMword) DSPregs[SRC1_REG].lower.i; - break; - - case 1: /* cfmvrdh */ - /* Move upper half of a DF stored in a DSP reg into an Arm reg. */ - printfdbg ("cfmvrdh\n"); - printfdbg ("\tupper half=0x%x\n", DSPregs[SRC1_REG].upper.i); - printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG)); - - *value = (ARMword) DSPregs[SRC1_REG].upper.i; - break; - - case 2: /* cfmvrs */ - /* Move SF from upper half of a DSP register to an Arm register. */ - *value = (ARMword) DSPregs[SRC1_REG].upper.i; - printfdbg ("cfmvrs = mvf%d <-- %f\n", - SRC1_REG, DSPregs[SRC1_REG].upper.f); - break; - -#ifdef doesnt_work - case 4: /* cfcmps */ - { - float a, b; - int n, z, c, v; - - a = DSPregs[SRC1_REG].upper.f; - b = DSPregs[SRC2_REG].upper.f; - - printfdbg ("cfcmps\n"); - printfdbg ("\tcomparing %f and %f\n", a, b); - - z = a == b; /* zero */ - n = a != b; /* negative */ - v = a > b; /* overflow */ - c = 0; /* carry */ - *value = (n << 31) | (z << 30) | (c << 29) | (v << - 28); - break; - } - - case 5: /* cfcmpd */ - { - double a, b; - int n, z, c, v; - - a = mv_getRegDouble (SRC1_REG); - b = mv_getRegDouble (SRC2_REG); - - printfdbg ("cfcmpd\n"); - printfdbg ("\tcomparing %g and %g\n", a, b); - - z = a == b; /* zero */ - n = a != b; /* negative */ - v = a > b; /* overflow */ - c = 0; /* carry */ - *value = (n << 31) | (z << 30) | (c << 29) | (v << - 28); - break; - } -#else - case 4: /* cfcmps */ - { - float a, b; - int n, z, c, v; - - a = DSPregs[SRC1_REG].upper.f; - b = DSPregs[SRC2_REG].upper.f; - - printfdbg ("cfcmps\n"); - printfdbg ("\tcomparing %f and %f\n", a, b); - - z = a == b; /* zero */ - n = a < b; /* negative */ - c = a > b; /* carry */ - v = 0; /* fixme */ - printfdbg ("\tz = %d, n = %d\n", z, n); - *value = (n << 31) | (z << 30) | (c << 29) | (v << - 28); - break; - } - - case 5: /* cfcmpd */ - { - double a, b; - int n, z, c, v; - - a = mv_getRegDouble (SRC1_REG); - b = mv_getRegDouble (SRC2_REG); - - printfdbg ("cfcmpd\n"); - printfdbg ("\tcomparing %g and %g\n", a, b); - - z = a == b; /* zero */ - n = a < b; /* negative */ - c = a > b; /* carry */ - v = 0; /* fixme */ - *value = (n << 31) | (z << 30) | (c << 29) | (v << - 28); - break; - } -#endif - default: - fprintf (stderr, "unknown opcode in DSPMRC4 0x%x\n", instr); - cirrus_not_implemented ("unknown"); - break; - } - - return ARMul_DONE; -} - -unsigned -DSPMRC5 (ARMul_State * state, - unsigned type, ARMword instr, ARMword * value) -{ - switch (BITS (5, 7)) { - case 0: /* cfmvr64l */ - /* Move lower half of 64bit int from Cirrus to Arm. */ - *value = (ARMword) DSPregs[SRC1_REG].lower.i; - printfdbg ("cfmvr64l ARM_REG = mvfx%d <-- %d\n", - DEST_REG, (int) *value); - break; - - case 1: /* cfmvr64h */ - /* Move upper half of 64bit int from Cirrus to Arm. */ - *value = (ARMword) DSPregs[SRC1_REG].upper.i; - printfdbg ("cfmvr64h <-- %d\n", (int) *value); - break; - - case 4: /* cfcmp32 */ - { - int res; - int n, z, c, v; - unsigned int a, b; - - printfdbg ("cfcmp32 mvfx%d - mvfx%d\n", SRC1_REG, - SRC2_REG); - - /* FIXME: see comment for cfcmps. */ - a = DSPregs[SRC1_REG].lower.i; - b = DSPregs[SRC2_REG].lower.i; - - res = DSPregs[SRC1_REG].lower.i - - DSPregs[SRC2_REG].lower.i; - /* zero */ - z = res == 0; - /* negative */ - n = res < 0; - /* overflow */ - v = SubOverflow (DSPregs[SRC1_REG].lower.i, - DSPregs[SRC2_REG].lower.i, res); - /* carry */ - c = (NEG (a) && POS (b) || - (NEG (a) && POS (res)) || (POS (b) - && POS (res))); - - *value = (n << 31) | (z << 30) | (c << 29) | (v << - 28); - break; - } - - case 5: /* cfcmp64 */ - { - long long res; - int n, z, c, v; - unsigned long long a, b; - - printfdbg ("cfcmp64 mvdx%d - mvdx%d\n", SRC1_REG, - SRC2_REG); - - /* fixme: see comment for cfcmps. */ - - a = mv_getReg64int (SRC1_REG); - b = mv_getReg64int (SRC2_REG); - - res = mv_getReg64int (SRC1_REG) - - mv_getReg64int (SRC2_REG); - /* zero */ - z = res == 0; - /* negative */ - n = res < 0; - /* overflow */ - v = ((NEG64 (a) && POS64 (b) && POS64 (res)) - || (POS64 (a) && NEG64 (b) && NEG64 (res))); - /* carry */ - c = (NEG64 (a) && POS64 (b) || - (NEG64 (a) && POS64 (res)) || (POS64 (b) - && POS64 (res))); - - *value = (n << 31) | (z << 30) | (c << 29) | (v << - 28); - break; - } - - default: - fprintf (stderr, "unknown opcode in DSPMRC5 0x%x\n", instr); - cirrus_not_implemented ("unknown"); - break; - } - - return ARMul_DONE; -} - -unsigned -DSPMRC6 (ARMul_State * state, - unsigned type, ARMword instr, ARMword * value) -{ - switch (BITS (5, 7)) { - case 0: /* cfmval32 */ - cirrus_not_implemented ("cfmval32"); - break; - - case 1: /* cfmvam32 */ - cirrus_not_implemented ("cfmvam32"); - break; - - case 2: /* cfmvah32 */ - cirrus_not_implemented ("cfmvah32"); - break; - - case 3: /* cfmva32 */ - cirrus_not_implemented ("cfmva32"); - break; - - case 4: /* cfmva64 */ - cirrus_not_implemented ("cfmva64"); - break; - - case 5: /* cfmvsc32 */ - cirrus_not_implemented ("cfmvsc32"); - break; - - default: - fprintf (stderr, "unknown opcode in DSPMRC6 0x%x\n", instr); - cirrus_not_implemented ("unknown"); - break; - } - - return ARMul_DONE; -} - -unsigned -DSPMCR4 (ARMul_State * state, - unsigned type, ARMword instr, ARMword value) -{ - switch (BITS (5, 7)) { - case 0: /* cfmvdlr */ - /* Move the lower half of a DF value from an Arm register into - the lower half of a Cirrus register. */ - printfdbg ("cfmvdlr <-- 0x%x\n", (int) value); - DSPregs[SRC1_REG].lower.i = (int) value; - break; - - case 1: /* cfmvdhr */ - /* Move the upper half of a DF value from an Arm register into - the upper half of a Cirrus register. */ - printfdbg ("cfmvdhr <-- 0x%x\n", (int) value); - DSPregs[SRC1_REG].upper.i = (int) value; - break; - - case 2: /* cfmvsr */ - /* Move SF from Arm register into upper half of Cirrus register. */ - printfdbg ("cfmvsr <-- 0x%x\n", (int) value); - DSPregs[SRC1_REG].upper.i = (int) value; - break; - - default: - fprintf (stderr, "unknown opcode in DSPMCR4 0x%x\n", instr); - cirrus_not_implemented ("unknown"); - break; - } - - return ARMul_DONE; -} - -unsigned -DSPMCR5 (ARMul_State * state, - unsigned type, ARMword instr, ARMword value) -{ - union - { - int s; - unsigned int us; - } val; - - switch (BITS (5, 7)) { - case 0: /* cfmv64lr */ - /* Move lower half of a 64bit int from an ARM register into the - lower half of a DSP register and sign extend it. */ - printfdbg ("cfmv64lr mvdx%d <-- 0x%x\n", SRC1_REG, - (int) value); - DSPregs[SRC1_REG].lower.i = (int) value; - break; - - case 1: /* cfmv64hr */ - /* Move upper half of a 64bit int from an ARM register into the - upper half of a DSP register. */ - printfdbg ("cfmv64hr ARM_REG = mvfx%d <-- 0x%x\n", - SRC1_REG, (int) value); - DSPregs[SRC1_REG].upper.i = (int) value; - break; - - case 2: /* cfrshl32 */ - printfdbg ("cfrshl32\n"); - val.us = value; - if (val.s > 0) - DSPregs[SRC2_REG].lower.i = - DSPregs[SRC1_REG].lower.i << value; - else - DSPregs[SRC2_REG].lower.i = - DSPregs[SRC1_REG].lower.i >> -value; - break; - - case 3: /* cfrshl64 */ - printfdbg ("cfrshl64\n"); - val.us = value; - if (val.s > 0) - mv_setReg64int (SRC2_REG, - mv_getReg64int (SRC1_REG) << value); - else - mv_setReg64int (SRC2_REG, - mv_getReg64int (SRC1_REG) >> -value); - break; - - default: - fprintf (stderr, "unknown opcode in DSPMCR5 0x%x\n", instr); - cirrus_not_implemented ("unknown"); - break; - } - - return ARMul_DONE; -} - -unsigned -DSPMCR6 (ARMul_State * state, - unsigned type, ARMword instr, ARMword value) -{ - switch (BITS (5, 7)) { - case 0: /* cfmv32al */ - cirrus_not_implemented ("cfmv32al"); - break; - - case 1: /* cfmv32am */ - cirrus_not_implemented ("cfmv32am"); - break; - - case 2: /* cfmv32ah */ - cirrus_not_implemented ("cfmv32ah"); - break; - - case 3: /* cfmv32a */ - cirrus_not_implemented ("cfmv32a"); - break; - - case 4: /* cfmv64a */ - cirrus_not_implemented ("cfmv64a"); - break; - - case 5: /* cfmv32sc */ - cirrus_not_implemented ("cfmv32sc"); - break; - - default: - fprintf (stderr, "unknown opcode in DSPMCR6 0x%x\n", instr); - cirrus_not_implemented ("unknown"); - break; - } - - return ARMul_DONE; -} - -unsigned -DSPLDC4 (ARMul_State * state, - unsigned type, ARMword instr, ARMword data) -{ - static unsigned words; - - if (type != ARMul_DATA) { - words = 0; - return ARMul_DONE; - } - - if (BIT (22)) { /* it's a long access, get two words */ - /* cfldrd */ - - printfdbg - ("cfldrd: %x (words = %d) (bigend = %d) DESTREG = %d\n", - data, words, state->bigendSig, DEST_REG); - - if (words == 0) { - if (state->bigendSig) - DSPregs[DEST_REG].upper.i = (int) data; - else - DSPregs[DEST_REG].lower.i = (int) data; - } - else { - if (state->bigendSig) - DSPregs[DEST_REG].lower.i = (int) data; - else - DSPregs[DEST_REG].upper.i = (int) data; - } - - ++words; - - if (words == 2) { - printfdbg ("\tmvd%d <-- mem = %g\n", DEST_REG, - mv_getRegDouble (DEST_REG)); - - return ARMul_DONE; - } - else - return ARMul_INC; - } - else { - /* Get just one word. */ - - /* cfldrs */ - printfdbg ("cfldrs\n"); - - DSPregs[DEST_REG].upper.i = (int) data; - - printfdbg ("\tmvf%d <-- mem = %f\n", DEST_REG, - DSPregs[DEST_REG].upper.f); - - return ARMul_DONE; - } -} - -unsigned -DSPLDC5 (ARMul_State * state, - unsigned type, ARMword instr, ARMword data) -{ - static unsigned words; - - if (type != ARMul_DATA) { - words = 0; - return ARMul_DONE; - } - - if (BIT (22)) { - /* It's a long access, get two words. */ - - /* cfldr64 */ - printfdbg ("cfldr64: %d\n", data); - - if (words == 0) { - if (state->bigendSig) - DSPregs[DEST_REG].upper.i = (int) data; - else - DSPregs[DEST_REG].lower.i = (int) data; - } - else { - if (state->bigendSig) - DSPregs[DEST_REG].lower.i = (int) data; - else - DSPregs[DEST_REG].upper.i = (int) data; - } - - ++words; - - if (words == 2) { - printfdbg ("\tmvdx%d <-- mem = %lld\n", DEST_REG, - mv_getReg64int (DEST_REG)); - - return ARMul_DONE; - } - else - return ARMul_INC; - } - else { - /* Get just one word. */ - - /* cfldr32 */ - printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data); - - /* 32bit ints should be sign extended to 64bits when loaded. */ - mv_setReg64int (DEST_REG, (long long) data); - - return ARMul_DONE; - } -} - -unsigned -DSPSTC4 (ARMul_State * state, - unsigned type, ARMword instr, ARMword * data) -{ - static unsigned words; - - if (type != ARMul_DATA) { - words = 0; - return ARMul_DONE; - } - - if (BIT (22)) { - /* It's a long access, get two words. */ - /* cfstrd */ - printfdbg ("cfstrd\n"); - - if (words == 0) { - if (state->bigendSig) - *data = (ARMword) DSPregs[DEST_REG].upper.i; - else - *data = (ARMword) DSPregs[DEST_REG].lower.i; - } - else { - if (state->bigendSig) - *data = (ARMword) DSPregs[DEST_REG].lower.i; - else - *data = (ARMword) DSPregs[DEST_REG].upper.i; - } - - ++words; - - if (words == 2) { - printfdbg ("\tmem = mvd%d = %g\n", DEST_REG, - mv_getRegDouble (DEST_REG)); - - return ARMul_DONE; - } - else - return ARMul_INC; - } - else { - /* Get just one word. */ - /* cfstrs */ - printfdbg ("cfstrs mvf%d <-- %f\n", DEST_REG, - DSPregs[DEST_REG].upper.f); - - *data = (ARMword) DSPregs[DEST_REG].upper.i; - - return ARMul_DONE; - } -} - -unsigned -DSPSTC5 (ARMul_State * state, - unsigned type, ARMword instr, ARMword * data) -{ - static unsigned words; - - if (type != ARMul_DATA) { - words = 0; - return ARMul_DONE; - } - - if (BIT (22)) { - /* It's a long access, store two words. */ - /* cfstr64 */ - printfdbg ("cfstr64\n"); - - if (words == 0) { - if (state->bigendSig) - *data = (ARMword) DSPregs[DEST_REG].upper.i; - else - *data = (ARMword) DSPregs[DEST_REG].lower.i; - } - else { - if (state->bigendSig) - *data = (ARMword) DSPregs[DEST_REG].lower.i; - else - *data = (ARMword) DSPregs[DEST_REG].upper.i; - } - - ++words; - - if (words == 2) { - printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG, - mv_getReg64int (DEST_REG)); - - return ARMul_DONE; - } - else - return ARMul_INC; - } - else { - /* Store just one word. */ - /* cfstr32 */ - *data = (ARMword) DSPregs[DEST_REG].lower.i; - - printfdbg ("cfstr32 MEM = %d\n", (int) *data); - - return ARMul_DONE; - } -} - -unsigned -DSPCDP4 (ARMul_State * state, unsigned type, ARMword instr) -{ - int opcode2; - - opcode2 = BITS (5, 7); - - switch (BITS (20, 21)) { - case 0: - switch (opcode2) { - case 0: /* cfcpys */ - printfdbg ("cfcpys mvf%d = mvf%d = %f\n", - DEST_REG, SRC1_REG, - DSPregs[SRC1_REG].upper.f); - DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f; - break; - - case 1: /* cfcpyd */ - printfdbg ("cfcpyd mvd%d = mvd%d = %g\n", - DEST_REG, SRC1_REG, - mv_getRegDouble (SRC1_REG)); - mv_setRegDouble (DEST_REG, - mv_getRegDouble (SRC1_REG)); - break; - - case 2: /* cfcvtds */ - printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n", - DEST_REG, SRC1_REG, - (float) mv_getRegDouble (SRC1_REG)); - DSPregs[DEST_REG].upper.f = - (float) mv_getRegDouble (SRC1_REG); - break; - - case 3: /* cfcvtsd */ - printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n", - DEST_REG, SRC1_REG, - (double) DSPregs[SRC1_REG].upper.f); - mv_setRegDouble (DEST_REG, - (double) DSPregs[SRC1_REG].upper.f); - break; - - case 4: /* cfcvt32s */ - printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n", - DEST_REG, SRC1_REG, - (float) DSPregs[SRC1_REG].lower.i); - DSPregs[DEST_REG].upper.f = - (float) DSPregs[SRC1_REG].lower.i; - break; - - case 5: /* cfcvt32d */ - printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n", - DEST_REG, SRC1_REG, - (double) DSPregs[SRC1_REG].lower.i); - mv_setRegDouble (DEST_REG, - (double) DSPregs[SRC1_REG].lower.i); - break; - - case 6: /* cfcvt64s */ - printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n", - DEST_REG, SRC1_REG, - (float) mv_getReg64int (SRC1_REG)); - DSPregs[DEST_REG].upper.f = - (float) mv_getReg64int (SRC1_REG); - break; - - case 7: /* cfcvt64d */ - printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n", - DEST_REG, SRC1_REG, - (double) mv_getReg64int (SRC1_REG)); - mv_setRegDouble (DEST_REG, - (double) mv_getReg64int (SRC1_REG)); - break; - } - break; - - case 1: - switch (opcode2) { - case 0: /* cfmuls */ - printfdbg ("cfmuls mvf%d = mvf%d = %f\n", - DEST_REG, - SRC1_REG, - DSPregs[SRC1_REG].upper.f * - DSPregs[SRC2_REG].upper.f); - - DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f - * DSPregs[SRC2_REG].upper.f; - break; - - case 1: /* cfmuld */ - printfdbg ("cfmuld mvd%d = mvd%d = %g\n", - DEST_REG, - SRC1_REG, - mv_getRegDouble (SRC1_REG) * - mv_getRegDouble (SRC2_REG)); - - mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG) - * mv_getRegDouble (SRC2_REG)); - break; - - default: - fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", - instr); - cirrus_not_implemented ("unknown"); - break; - } - break; - - case 3: - switch (opcode2) { - case 0: /* cfabss */ - DSPregs[DEST_REG].upper.f = - (DSPregs[SRC1_REG].upper.f < - 0.0F ? -DSPregs[SRC1_REG].upper. - f : DSPregs[SRC1_REG].upper.f); - printfdbg ("cfabss mvf%d = |mvf%d| = %f\n", DEST_REG, - SRC1_REG, DSPregs[DEST_REG].upper.f); - break; - - case 1: /* cfabsd */ - mv_setRegDouble (DEST_REG, - (mv_getRegDouble (SRC1_REG) < 0.0 ? - -mv_getRegDouble (SRC1_REG) - : mv_getRegDouble (SRC1_REG))); - printfdbg ("cfabsd mvd%d = |mvd%d| = %g\n", - DEST_REG, SRC1_REG, - mv_getRegDouble (DEST_REG)); - break; - - case 2: /* cfnegs */ - DSPregs[DEST_REG].upper.f = - -DSPregs[SRC1_REG].upper.f; - printfdbg ("cfnegs mvf%d = -mvf%d = %f\n", DEST_REG, - SRC1_REG, DSPregs[DEST_REG].upper.f); - break; - - case 3: /* cfnegd */ - mv_setRegDouble (DEST_REG, - -mv_getRegDouble (SRC1_REG)); - printfdbg ("cfnegd mvd%d = -mvd%d = %g\n", DEST_REG, - mv_getRegDouble (DEST_REG)); - break; - - case 4: /* cfadds */ - DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f - + DSPregs[SRC2_REG].upper.f; - printfdbg ("cfadds mvf%d = mvf%d + mvf%d = %f\n", - DEST_REG, SRC1_REG, SRC2_REG, - DSPregs[DEST_REG].upper.f); - break; - - case 5: /* cfaddd */ - mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG) - + mv_getRegDouble (SRC2_REG)); - printfdbg ("cfaddd: mvd%d = mvd%d + mvd%d = %g\n", - DEST_REG, - SRC1_REG, SRC2_REG, - mv_getRegDouble (DEST_REG)); - break; - - case 6: /* cfsubs */ - DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f - - DSPregs[SRC2_REG].upper.f; - printfdbg ("cfsubs: mvf%d = mvf%d - mvf%d = %f\n", - DEST_REG, SRC1_REG, SRC2_REG, - DSPregs[DEST_REG].upper.f); - break; - - case 7: /* cfsubd */ - mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG) - - mv_getRegDouble (SRC2_REG)); - printfdbg ("cfsubd: mvd%d = mvd%d - mvd%d = %g\n", - DEST_REG, - SRC1_REG, SRC2_REG, - mv_getRegDouble (DEST_REG)); - break; - } - break; - - default: - fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr); - cirrus_not_implemented ("unknown"); - break; - } - - return ARMul_DONE; -} - -unsigned -DSPCDP5 (ARMul_State * state, unsigned type, ARMword instr) -{ - int opcode2; - char shift; - - opcode2 = BITS (5, 7); - - /* Shift constants are 7bit signed numbers in bits 0..3|5..7. */ - shift = BITS (0, 3) | (BITS (5, 7)) << 4; - if (shift & 0x40) - shift |= 0xc0; - - switch (BITS (20, 21)) { - case 0: - /* cfsh32 */ - printfdbg ("cfsh32 %s amount=%d\n", - shift < 0 ? "right" : "left", shift); - if (shift < 0) - /* Negative shift is a right shift. */ - DSPregs[DEST_REG].lower.i = - DSPregs[SRC1_REG].lower.i >> -shift; - else - /* Positive shift is a left shift. */ - DSPregs[DEST_REG].lower.i = - DSPregs[SRC1_REG].lower.i << shift; - break; - - case 1: - switch (opcode2) { - case 0: /* cfmul32 */ - DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i - * DSPregs[SRC2_REG].lower.i; - printfdbg ("cfmul32 mvfx%d = mvfx%d * mvfx%d = %d\n", - DEST_REG, SRC1_REG, SRC2_REG, - DSPregs[DEST_REG].lower.i); - break; - - case 1: /* cfmul64 */ - mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG) - * mv_getReg64int (SRC2_REG)); - printfdbg - ("cfmul64 mvdx%d = mvdx%d * mvdx%d = %lld\n", - DEST_REG, SRC1_REG, SRC2_REG, - mv_getReg64int (DEST_REG)); - break; - - case 2: /* cfmac32 */ - DSPregs[DEST_REG].lower.i - += - DSPregs[SRC1_REG].lower.i * - DSPregs[SRC2_REG].lower.i; - printfdbg ("cfmac32 mvfx%d += mvfx%d * mvfx%d = %d\n", - DEST_REG, SRC1_REG, SRC2_REG, - DSPregs[DEST_REG].lower.i); - break; - - case 3: /* cfmsc32 */ - DSPregs[DEST_REG].lower.i - -= - DSPregs[SRC1_REG].lower.i * - DSPregs[SRC2_REG].lower.i; - printfdbg ("cfmsc32 mvfx%d -= mvfx%d * mvfx%d = %d\n", - DEST_REG, SRC1_REG, SRC2_REG, - DSPregs[DEST_REG].lower.i); - break; - - case 4: /* cfcvts32 */ - /* fixme: this should round */ - DSPregs[DEST_REG].lower.i = - (int) DSPregs[SRC1_REG].upper.f; - printfdbg ("cfcvts32 mvfx%d = mvf%d = %d\n", DEST_REG, - SRC1_REG, DSPregs[DEST_REG].lower.i); - break; - - case 5: /* cfcvtd32 */ - /* fixme: this should round */ - DSPregs[DEST_REG].lower.i = - (int) mv_getRegDouble (SRC1_REG); - printfdbg ("cfcvtd32 mvdx%d = mvd%d = %d\n", DEST_REG, - SRC1_REG, DSPregs[DEST_REG].lower.i); - break; - - case 6: /* cftruncs32 */ - DSPregs[DEST_REG].lower.i = - (int) DSPregs[SRC1_REG].upper.f; - printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n", - DEST_REG, SRC1_REG, - DSPregs[DEST_REG].lower.i); - break; - - case 7: /* cftruncd32 */ - DSPregs[DEST_REG].lower.i = - (int) mv_getRegDouble (SRC1_REG); - printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n", - DEST_REG, SRC1_REG, - DSPregs[DEST_REG].lower.i); - break; - } - break; - - case 2: - /* cfsh64 */ - printfdbg ("cfsh64\n"); - - if (shift < 0) - /* Negative shift is a right shift. */ - mv_setReg64int (DEST_REG, - mv_getReg64int (SRC1_REG) >> -shift); - else - /* Positive shift is a left shift. */ - mv_setReg64int (DEST_REG, - mv_getReg64int (SRC1_REG) << shift); - printfdbg ("\t%llx\n", mv_getReg64int (DEST_REG)); - break; - - case 3: - switch (opcode2) { - case 0: /* cfabs32 */ - DSPregs[DEST_REG].lower.i = - (DSPregs[SRC1_REG].lower.i < - 0 ? -DSPregs[SRC1_REG].lower. - i : DSPregs[SRC1_REG].lower.i); - printfdbg ("cfabs32 mvfx%d = |mvfx%d| = %d\n", - DEST_REG, SRC1_REG, SRC2_REG, - DSPregs[DEST_REG].lower.i); - break; - - case 1: /* cfabs64 */ - mv_setReg64int (DEST_REG, - (mv_getReg64int (SRC1_REG) < 0 - ? -mv_getReg64int (SRC1_REG) - : mv_getReg64int (SRC1_REG))); - printfdbg ("cfabs64 mvdx%d = |mvdx%d| = %lld\n", - DEST_REG, SRC1_REG, SRC2_REG, - mv_getReg64int (DEST_REG)); - break; - - case 2: /* cfneg32 */ - DSPregs[DEST_REG].lower.i = - -DSPregs[SRC1_REG].lower.i; - printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n", - DEST_REG, SRC1_REG, SRC2_REG, - DSPregs[DEST_REG].lower.i); - break; - - case 3: /* cfneg64 */ - mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG)); - printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n", - DEST_REG, SRC1_REG, SRC2_REG, - mv_getReg64int (DEST_REG)); - break; - - case 4: /* cfadd32 */ - DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i - + DSPregs[SRC2_REG].lower.i; - printfdbg ("cfadd32 mvfx%d = mvfx%d + mvfx%d = %d\n", - DEST_REG, SRC1_REG, SRC2_REG, - DSPregs[DEST_REG].lower.i); - break; - - case 5: /* cfadd64 */ - mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG) - + mv_getReg64int (SRC2_REG)); - printfdbg - ("cfadd64 mvdx%d = mvdx%d + mvdx%d = %lld\n", - DEST_REG, SRC1_REG, SRC2_REG, - mv_getReg64int (DEST_REG)); - break; - - case 6: /* cfsub32 */ - DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i - - DSPregs[SRC2_REG].lower.i; - printfdbg ("cfsub32 mvfx%d = mvfx%d - mvfx%d = %d\n", - DEST_REG, SRC1_REG, SRC2_REG, - DSPregs[DEST_REG].lower.i); - break; - - case 7: /* cfsub64 */ - mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG) - - mv_getReg64int (SRC2_REG)); - printfdbg ("cfsub64 mvdx%d = mvdx%d - mvdx%d = %d\n", - DEST_REG, SRC1_REG, SRC2_REG, - mv_getReg64int (DEST_REG)); - break; - } - break; - - default: - fprintf (stderr, "unknown opcode in DSPCDP5 0x%x\n", instr); - cirrus_not_implemented ("unknown"); - break; - } - - return ARMul_DONE; -} - -unsigned -DSPCDP6 (ARMul_State * state, unsigned type, ARMword instr) -{ - int opcode2; - - opcode2 = BITS (5, 7); - - switch (BITS (20, 21)) { - case 0: - /* cfmadd32 */ - cirrus_not_implemented ("cfmadd32"); - break; - - case 1: - /* cfmsub32 */ - cirrus_not_implemented ("cfmsub32"); - break; - - case 2: - /* cfmadda32 */ - cirrus_not_implemented ("cfmadda32"); - break; - - case 3: - /* cfmsuba32 */ - cirrus_not_implemented ("cfmsuba32"); - break; - - default: - fprintf (stderr, "unknown opcode in DSPCDP6 0x%x\n", instr); - } - - return ARMul_DONE; -} - -/* Conversion functions. - - 32-bit integers are stored in the LOWER half of a 64-bit physical - register. - - Single precision floats are stored in the UPPER half of a 64-bit - physical register. */ - -static double -mv_getRegDouble (int regnum) -{ - reg_conv.ints[lsw_float_index] = DSPregs[regnum].upper.i; - reg_conv.ints[msw_float_index] = DSPregs[regnum].lower.i; - return reg_conv.d; -} - -static void -mv_setRegDouble (int regnum, double val) -{ - reg_conv.d = val; - DSPregs[regnum].upper.i = reg_conv.ints[lsw_float_index]; - DSPregs[regnum].lower.i = reg_conv.ints[msw_float_index]; -} - -static long long -mv_getReg64int (int regnum) -{ - reg_conv.ints[lsw_int_index] = DSPregs[regnum].lower.i; - reg_conv.ints[msw_int_index] = DSPregs[regnum].upper.i; - return reg_conv.ll; -} - -static void -mv_setReg64int (int regnum, long long val) -{ - reg_conv.ll = val; - DSPregs[regnum].lower.i = reg_conv.ints[lsw_int_index]; - DSPregs[regnum].upper.i = reg_conv.ints[msw_int_index]; -} - -/* Compute LSW in a double and a long long. */ - -void -mv_compute_host_endianness (ARMul_State * state) -{ - static union - { - long long ll; - int ints[2]; - int i; - double d; - float floats[2]; - float f; - } conv; - - /* Calculate where's the LSW in a 64bit int. */ - conv.ll = 45; - - if (conv.ints[0] == 0) { - msw_int_index = 0; - lsw_int_index = 1; - } - else { - assert (conv.ints[1] == 0); - msw_int_index = 1; - lsw_int_index = 0; - } - - /* Calculate where's the LSW in a double. */ - conv.d = 3.0; - - if (conv.ints[0] == 0) { - msw_float_index = 0; - lsw_float_index = 1; - } - else { - assert (conv.ints[1] == 0); - msw_float_index = 1; - lsw_float_index = 0; - } - - printfdbg ("lsw_int_index %d\n", lsw_int_index); - printfdbg ("lsw_float_index %d\n", lsw_float_index); -} diff --git a/src/core/arm/interpreter/mmu/rb.cpp b/src/core/arm/interpreter/mmu/rb.cpp deleted file mode 100644 index 600c9d8c8..000000000 --- a/src/core/arm/interpreter/mmu/rb.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "core/arm/skyeye_common/armdefs.h" - -/*chy 2004-06-06, fix bug found by wenye@cs.ucsb.edu*/ -ARMword rb_masks[] = { - 0x0, //RB_INVALID - 4, //RB_1 - 16, //RB_4 - 32, //RB_8 -}; - -/*mmu_rb_init - * @rb_t :rb_t to init - * @num :number of entry - * */ -int -mmu_rb_init (rb_s * rb_t, int num) -{ - int i; - rb_entry_t *entrys; - - entrys = (rb_entry_t *) malloc (sizeof (*entrys) * num); - if (entrys == NULL) { - printf ("SKYEYE:mmu_rb_init malloc error\n"); - return -1; - } - for (i = 0; i < num; i++) { - entrys[i].type = RB_INVALID; - entrys[i].fault = NO_FAULT; - } - - rb_t->entrys = entrys; - rb_t->num = num; - return 0; -} - -/*mmu_rb_exit*/ -void -mmu_rb_exit (rb_s * rb_t) -{ - free (rb_t->entrys); -}; - -/*mmu_rb_search - * @rb_t :rb_t to serach - * @va :va address to math - * - * $ NULL :not match - * NO-NULL: - * */ -rb_entry_t * -mmu_rb_search (rb_s * rb_t, ARMword va) -{ - int i; - rb_entry_t *rb = rb_t->entrys; - - DEBUG_LOG(ARM11, "va = %x\n", va); - for (i = 0; i < rb_t->num; i++, rb++) { - //2004-06-06 lyh bug from wenye@cs.ucsb.edu - if (rb->type) { - if ((va >= rb->va) - && (va < (rb->va + rb_masks[rb->type]))) - return rb; - } - } - return NULL; -}; - -void -mmu_rb_invalidate_entry (rb_s * rb_t, int i) -{ - rb_t->entrys[i].type = RB_INVALID; -} - -void -mmu_rb_invalidate_all (rb_s * rb_t) -{ - int i; - - for (i = 0; i < rb_t->num; i++) - mmu_rb_invalidate_entry (rb_t, i); -}; - -void -mmu_rb_load (ARMul_State * state, rb_s * rb_t, int i_rb, int type, ARMword va) -{ - rb_entry_t *rb; - int i; - ARMword max_start, min_end; - fault_t fault; - tlb_entry_t *tlb; - - /*align va according to type */ - va &= ~(rb_masks[type] - 1); - /*invalidate all RB match [va, va + rb_masks[type]] */ - for (rb = rb_t->entrys, i = 0; i < rb_t->num; i++, rb++) { - if (rb->type) { - max_start = max (va, rb->va); - min_end = - min (va + rb_masks[type], - rb->va + rb_masks[rb->type]); - if (max_start < min_end) - rb->type = RB_INVALID; - } - } - /*load word */ - rb = &rb_t->entrys[i_rb]; - rb->type = type; - fault = translate (state, va, D_TLB (), &tlb); - if (fault) { - rb->fault = fault; - return; - } - fault = check_access (state, va, tlb, 1); - if (fault) { - rb->fault = fault; - return; - } - - rb->fault = NO_FAULT; - va = tlb_va_to_pa (tlb, va); - //2004-06-06 lyh bug from wenye@cs.ucsb.edu - for (i = 0; i < (rb_masks[type] / 4); i++, va += WORD_SIZE) { - //rb->data[i] = mem_read_word (state, va); - bus_read(32, va, &rb->data[i]); - }; -} diff --git a/src/core/arm/interpreter/mmu/rb.h b/src/core/arm/interpreter/mmu/rb.h deleted file mode 100644 index 7bf0ebb26..000000000 --- a/src/core/arm/interpreter/mmu/rb.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _MMU_RB_H -#define _MMU_RB_H - -enum rb_type_t -{ - RB_INVALID = 0, //invalid - RB_1, //1 word - RB_4, //4 word - RB_8, //8 word -}; - -/*bytes of each rb_type*/ -extern ARMword rb_masks[]; - -#define RB_WORD_NUM 8 -typedef struct rb_entry_s -{ - ARMword data[RB_WORD_NUM]; //array to store data - ARMword va; //first word va - int type; //rb type - fault_t fault; //fault set by rb alloc -} rb_entry_t; - -typedef struct rb_s -{ - int num; - rb_entry_t *entrys; -} rb_s; - -/*mmu_rb_init - * @rb_t :rb_t to init - * @num :number of entry - * */ -int mmu_rb_init (rb_s * rb_t, int num); - -/*mmu_rb_exit*/ -void mmu_rb_exit (rb_s * rb_t); - - -/*mmu_rb_search - * @rb_t :rb_t to serach - * @va :va address to math - * - * $ NULL :not match - * NO-NULL: - * */ -rb_entry_t *mmu_rb_search (rb_s * rb_t, ARMword va); - - -void mmu_rb_invalidate_entry (rb_s * rb_t, int i); -void mmu_rb_invalidate_all (rb_s * rb_t); -void mmu_rb_load (ARMul_State * state, rb_s * rb_t, int i_rb, - int type, ARMword va); - -#endif /*_MMU_RB_H_*/ diff --git a/src/core/arm/interpreter/mmu/sa_mmu.cpp b/src/core/arm/interpreter/mmu/sa_mmu.cpp deleted file mode 100644 index 27f9ec8e0..000000000 --- a/src/core/arm/interpreter/mmu/sa_mmu.cpp +++ /dev/null @@ -1,864 +0,0 @@ -/* - armmmu.c - Memory Management Unit emulation. - ARMulator extensions for the ARM7100 family. - Copyright (C) 1999 Ben Williamson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include <assert.h> -#include <string.h> - -#include "core/arm/skyeye_common/armdefs.h" - -/** - * The interface of read data from bus - */ -int bus_read(short size, int addr, uint32_t * value) { - ERROR_LOG(ARM11, "unimplemented bus_read"); - return 0; -} - -/** - * The interface of write data from bus - */ -int bus_write(short size, int addr, uint32_t value) { - ERROR_LOG(ARM11, "unimplemented bus_write"); - return 0; -} - - -typedef struct sa_mmu_desc_s -{ - int i_tlb; - cache_desc_t i_cache; - - int d_tlb; - cache_desc_t main_d_cache; - cache_desc_t mini_d_cache; - int rb; - wb_desc_t wb; -} sa_mmu_desc_t; - -static sa_mmu_desc_t sa11xx_mmu_desc = { - 32, - {32, 32, 16, CACHE_WRITE_BACK}, - - 32, - {32, 32, 8, CACHE_WRITE_BACK}, - {32, 2, 8, CACHE_WRITE_BACK}, - 4, - //{8, 4}, for word size - {8, 16}, //for byte size, chy 2003-07-11 -}; - -static fault_t sa_mmu_write (ARMul_State * state, ARMword va, ARMword data, - ARMword datatype); -static fault_t sa_mmu_read (ARMul_State * state, ARMword va, ARMword * data, - ARMword datatype); -static fault_t update_cache (ARMul_State * state, ARMword va, ARMword data, - ARMword datatype, cache_line_t * cache, - cache_s * cache_t, ARMword real_va); - -void -mmu_wb_write_bytes (ARMul_State * state, wb_s * wb_t, ARMword pa, - ARMbyte * data, int n); -int -sa_mmu_init (ARMul_State * state) -{ - sa_mmu_desc_t *desc; - cache_desc_t *c_desc; - - state->mmu.control = 0x70; - state->mmu.translation_table_base = 0xDEADC0DE; - state->mmu.domain_access_control = 0xDEADC0DE; - state->mmu.fault_status = 0; - state->mmu.fault_address = 0; - state->mmu.process_id = 0; - - desc = &sa11xx_mmu_desc; - if (mmu_tlb_init (I_TLB (), desc->i_tlb)) { - ERROR_LOG(ARM11, "i_tlb init %d\n", -1); - goto i_tlb_init_error; - } - - c_desc = &desc->i_cache; - if (mmu_cache_init (I_CACHE (), c_desc->width, c_desc->way, - c_desc->set, c_desc->w_mode)) { - ERROR_LOG(ARM11, "i_cache init %d\n", -1); - goto i_cache_init_error; - } - - if (mmu_tlb_init (D_TLB (), desc->d_tlb)) { - ERROR_LOG(ARM11, "d_tlb init %d\n", -1); - goto d_tlb_init_error; - } - - c_desc = &desc->main_d_cache; - if (mmu_cache_init (MAIN_D_CACHE (), c_desc->width, c_desc->way, - c_desc->set, c_desc->w_mode)) { - ERROR_LOG(ARM11, "main_d_cache init %d\n", -1); - goto main_d_cache_init_error; - } - - c_desc = &desc->mini_d_cache; - if (mmu_cache_init (MINI_D_CACHE (), c_desc->width, c_desc->way, - c_desc->set, c_desc->w_mode)) { - ERROR_LOG(ARM11, "mini_d_cache init %d\n", -1); - goto mini_d_cache_init_error; - } - - if (mmu_wb_init (WB (), desc->wb.num, desc->wb.nb)) { - ERROR_LOG(ARM11, "wb init %d\n", -1); - goto wb_init_error; - } - - if (mmu_rb_init (RB (), desc->rb)) { - ERROR_LOG(ARM11, "rb init %d\n", -1); - goto rb_init_error; - } - return 0; - - rb_init_error: - mmu_wb_exit (WB ()); - wb_init_error: - mmu_cache_exit (MINI_D_CACHE ()); - mini_d_cache_init_error: - mmu_cache_exit (MAIN_D_CACHE ()); - main_d_cache_init_error: - mmu_tlb_exit (D_TLB ()); - d_tlb_init_error: - mmu_cache_exit (I_CACHE ()); - i_cache_init_error: - mmu_tlb_exit (I_TLB ()); - i_tlb_init_error: - return -1; -} - -void -sa_mmu_exit (ARMul_State * state) -{ - mmu_rb_exit (RB ()); - mmu_wb_exit (WB ()); - mmu_cache_exit (MINI_D_CACHE ()); - mmu_cache_exit (MAIN_D_CACHE ()); - mmu_tlb_exit (D_TLB ()); - mmu_cache_exit (I_CACHE ()); - mmu_tlb_exit (I_TLB ()); -}; - - -static fault_t -sa_mmu_load_instr (ARMul_State * state, ARMword va, ARMword * instr) -{ - fault_t fault; - tlb_entry_t *tlb; - cache_line_t *cache; - int c; //cache bit - ARMword pa; //physical addr - - static int debug_count = 0; //used for debug - - DEBUG_LOG(ARM11, "va = %x\n", va); - - va = mmu_pid_va_map (va); - if (MMU_Enabled) { - /*align check */ - if ((va & (WORD_SIZE - 1)) && MMU_Aligned) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } - else - va &= ~(WORD_SIZE - 1); - - /*translate tlb */ - fault = translate (state, va, I_TLB (), &tlb); - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - return fault; - } - - /*check access */ - fault = check_access (state, va, tlb, 1); - if (fault) { - DEBUG_LOG(ARM11, "check_fault\n"); - return fault; - } - } - - /*search cache no matter MMU enabled/disabled */ - cache = mmu_cache_search (state, I_CACHE (), va); - if (cache) { - *instr = cache->data[va_cache_index (va, I_CACHE ())]; - return NO_FAULT; - } - - /*if MMU disabled or C flag is set alloc cache */ - if (MMU_Disabled) { - c = 1; - pa = va; - } - else { - c = tlb_c_flag (tlb); - pa = tlb_va_to_pa (tlb, va); - } - - if (c) { - int index; - - debug_count++; - cache = mmu_cache_alloc (state, I_CACHE (), va, pa); - index = va_cache_index (va, I_CACHE ()); - *instr = cache->data[va_cache_index (va, I_CACHE ())]; - } - else - //*instr = mem_read_word (state, pa); - bus_read(32, pa, instr); - - return NO_FAULT; -}; - - - -static fault_t -sa_mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data) -{ - //ARMword temp,offset; - fault_t fault; - fault = sa_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE); - return fault; -} - -static fault_t -sa_mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data) -{ - //ARMword temp,offset; - fault_t fault; - fault = sa_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE); - return fault; -} - -static fault_t -sa_mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data) -{ - return sa_mmu_read (state, virt_addr, data, ARM_WORD_TYPE); -} - - - - -static fault_t -sa_mmu_read (ARMul_State * state, ARMword va, ARMword * data, - ARMword datatype) -{ - fault_t fault; - rb_entry_t *rb; - tlb_entry_t *tlb; - cache_line_t *cache; - ARMword pa, real_va, temp, offset; - - DEBUG_LOG(ARM11, "va = %x\n", va); - - va = mmu_pid_va_map (va); - real_va = va; - /*if MMU disabled, memory_read */ - if (MMU_Disabled) { - //*data = mem_read_word(state, va); - if (datatype == ARM_BYTE_TYPE) - //*data = mem_read_byte (state, va); - bus_read(8, va, data); - else if (datatype == ARM_HALFWORD_TYPE) - //*data = mem_read_halfword (state, va); - bus_read(16, va, data); - else if (datatype == ARM_WORD_TYPE) - //*data = mem_read_word (state, va); - bus_read(32, va, data); - else { - printf ("SKYEYE:1 sa_mmu_read error: unknown data type %d\n", datatype); - // skyeye_exit (-1); - } - - return NO_FAULT; - } - - /*align check */ - if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) || - ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } // else - - va &= ~(WORD_SIZE - 1); - - /*translate va to tlb */ - fault = translate (state, va, D_TLB (), &tlb); - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - return fault; - } - /*check access permission */ - fault = check_access (state, va, tlb, 1); - if (fault) - return fault; - /*search in read buffer */ - rb = mmu_rb_search (RB (), va); - if (rb) { - if (rb->fault) - return rb->fault; - *data = rb->data[(va & (rb_masks[rb->type] - 1)) >> WORD_SHT]; - goto datatrans; - //return 0; - }; - /*search main cache */ - cache = mmu_cache_search (state, MAIN_D_CACHE (), va); - if (cache) { - *data = cache->data[va_cache_index (va, MAIN_D_CACHE ())]; - goto datatrans; - //return 0; - } - /*search mini cache */ - cache = mmu_cache_search (state, MINI_D_CACHE (), va); - if (cache) { - *data = cache->data[va_cache_index (va, MINI_D_CACHE ())]; - goto datatrans; - //return 0; - } - - /*get phy_addr */ - pa = tlb_va_to_pa (tlb, va); - if ((pa >= 0xe0000000) && (pa < 0xe8000000)) { - if (tlb_c_flag (tlb)) { - if (tlb_b_flag (tlb)) { - mmu_cache_soft_flush (state, MAIN_D_CACHE (), - pa); - } - else { - mmu_cache_soft_flush (state, MINI_D_CACHE (), - pa); - } - } - return NO_FAULT; - } - - /*if Buffer, drain Write Buffer first */ - if (tlb_b_flag (tlb)) - mmu_wb_drain_all (state, WB ()); - - /*alloc cache or mem_read */ - if (tlb_c_flag (tlb) && MMU_DCacheEnabled) { - cache_s *cache_t; - - if (tlb_b_flag (tlb)) - cache_t = MAIN_D_CACHE (); - else - cache_t = MINI_D_CACHE (); - cache = mmu_cache_alloc (state, cache_t, va, pa); - *data = cache->data[va_cache_index (va, cache_t)]; - } - else { - //*data = mem_read_word(state, pa); - if (datatype == ARM_BYTE_TYPE) - //*data = mem_read_byte (state, pa | (real_va & 3)); - bus_read(8, pa | (real_va & 3), data); - else if (datatype == ARM_HALFWORD_TYPE) - //*data = mem_read_halfword (state, pa | (real_va & 2)); - bus_read(16, pa | (real_va & 2), data); - else if (datatype == ARM_WORD_TYPE) - //*data = mem_read_word (state, pa); - bus_read(32, pa, data); - else { - printf ("SKYEYE:2 sa_mmu_read error: unknown data type %d\n", datatype); - // skyeye_exit (-1); - } - return NO_FAULT; - } - - - datatrans: - if (datatype == ARM_HALFWORD_TYPE) { - temp = *data; - offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */ - *data = (temp >> offset) & 0xffff; - } - else if (datatype == ARM_BYTE_TYPE) { - temp = *data; - offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */ - *data = (temp >> offset & 0xffL); - } - end: - return NO_FAULT; -} - - -static fault_t -sa_mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data) -{ - return sa_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE); -} - -static fault_t -sa_mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data) -{ - return sa_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE); -} - -static fault_t -sa_mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data) -{ - return sa_mmu_write (state, virt_addr, data, ARM_WORD_TYPE); -} - - - -static fault_t -sa_mmu_write (ARMul_State * state, ARMword va, ARMword data, ARMword datatype) -{ - tlb_entry_t *tlb; - cache_line_t *cache; - int b; - ARMword pa, real_va; - fault_t fault; - - DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data); - va = mmu_pid_va_map (va); - real_va = va; - - /*search instruction cache */ - cache = mmu_cache_search (state, I_CACHE (), va); - if (cache) { - update_cache (state, va, data, datatype, cache, I_CACHE (), - real_va); - } - - if (MMU_Disabled) { - //mem_write_word(state, va, data); - if (datatype == ARM_BYTE_TYPE) - //mem_write_byte (state, va, data); - bus_write(8, va, data); - else if (datatype == ARM_HALFWORD_TYPE) - //mem_write_halfword (state, va, data); - bus_write(16, va, data); - else if (datatype == ARM_WORD_TYPE) - //mem_write_word (state, va, data); - bus_write(32, va, data); - else { - printf ("SKYEYE:1 sa_mmu_write error: unknown data type %d\n", datatype); - // skyeye_exit (-1); - } - - return NO_FAULT; - } - /*align check */ - //if ((va & (WORD_SIZE - 1)) && MMU_Aligned){ - if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) || - ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } //else - va &= ~(WORD_SIZE - 1); - /*tlb translate */ - fault = translate (state, va, D_TLB (), &tlb); - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - return fault; - } - /*tlb check access */ - fault = check_access (state, va, tlb, 0); - if (fault) { - DEBUG_LOG(ARM11, "check_access\n"); - return fault; - } - /*search main cache */ - cache = mmu_cache_search (state, MAIN_D_CACHE (), va); - if (cache) { - update_cache (state, va, data, datatype, cache, - MAIN_D_CACHE (), real_va); - } - else { - /*search mini cache */ - cache = mmu_cache_search (state, MINI_D_CACHE (), va); - if (cache) { - update_cache (state, va, data, datatype, cache, - MINI_D_CACHE (), real_va); - } - } - - if (!cache) { - b = tlb_b_flag (tlb); - pa = tlb_va_to_pa (tlb, va); - if (b) { - if (MMU_WBEnabled) { - if (datatype == ARM_WORD_TYPE) - mmu_wb_write_bytes (state, WB (), pa, - (ARMbyte*)&data, 4); - else if (datatype == ARM_HALFWORD_TYPE) - mmu_wb_write_bytes (state, WB (), - (pa | - (real_va & 2)), - (ARMbyte*)&data, 2); - else if (datatype == ARM_BYTE_TYPE) - mmu_wb_write_bytes (state, WB (), - (pa | - (real_va & 3)), - (ARMbyte*)&data, 1); - - } - else { - if (datatype == ARM_WORD_TYPE) - //mem_write_word (state, pa, data); - bus_write(32, pa, data); - else if (datatype == ARM_HALFWORD_TYPE) - /* - mem_write_halfword (state, - (pa | - (real_va & 2)), - data); - */ - bus_write(16, pa | (real_va & 2), data); - else if (datatype == ARM_BYTE_TYPE) - /* - mem_write_byte (state, - (pa | (real_va & 3)), - data); - */ - bus_write(8, pa | (real_va & 3), data); - } - } - else { - mmu_wb_drain_all (state, WB ()); - - if (datatype == ARM_WORD_TYPE) - //mem_write_word (state, pa, data); - bus_write(32, pa, data); - else if (datatype == ARM_HALFWORD_TYPE) - /* - mem_write_halfword (state, - (pa | (real_va & 2)), - data); - */ - bus_write(16, pa | (real_va & 2), data); - else if (datatype == ARM_BYTE_TYPE) - /* - mem_write_byte (state, (pa | (real_va & 3)), - data); - */ - bus_write(8, pa | (real_va & 3), data); - } - } - return NO_FAULT; -} - -static fault_t -update_cache (ARMul_State * state, ARMword va, ARMword data, ARMword datatype, - cache_line_t * cache, cache_s * cache_t, ARMword real_va) -{ - ARMword temp, offset; - - ARMword index = va_cache_index (va, cache_t); - - //cache->data[index] = data; - - if (datatype == ARM_WORD_TYPE) - cache->data[index] = data; - else if (datatype == ARM_HALFWORD_TYPE) { - temp = cache->data[index]; - offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */ - cache->data[index] = - (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << - offset); - } - else if (datatype == ARM_BYTE_TYPE) { - temp = cache->data[index]; - offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */ - cache->data[index] = - (temp & ~(0xffL << offset)) | ((data & 0xffL) << - offset); - } - - if (index < (cache_t->width >> (WORD_SHT + 1))) - cache->tag |= TAG_FIRST_HALF_DIRTY; - else - cache->tag |= TAG_LAST_HALF_DIRTY; - - return NO_FAULT; -} - -ARMword -sa_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value) -{ - mmu_regnum_t creg = (mmu_regnum_t)(BITS (16, 19) & 15); - ARMword data; - - switch (creg) { - case MMU_ID: -// printf("mmu_mrc read ID "); - data = 0x41007100; /* v3 */ - data = state->cpu->cpu_val; - break; - case MMU_CONTROL: -// printf("mmu_mrc read CONTROL"); - data = state->mmu.control; - break; - case MMU_TRANSLATION_TABLE_BASE: -// printf("mmu_mrc read TTB "); - data = state->mmu.translation_table_base; - break; - case MMU_DOMAIN_ACCESS_CONTROL: -// printf("mmu_mrc read DACR "); - data = state->mmu.domain_access_control; - break; - case MMU_FAULT_STATUS: -// printf("mmu_mrc read FSR "); - data = state->mmu.fault_status; - break; - case MMU_FAULT_ADDRESS: -// printf("mmu_mrc read FAR "); - data = state->mmu.fault_address; - break; - case MMU_PID: - data = state->mmu.process_id; - default: - printf ("mmu_mrc read UNKNOWN - reg %d\n", creg); - data = 0; - break; - } -// printf("\t\t\t\t\tpc = 0x%08x\n", state->Reg[15]); - *value = data; - return data; -} - -void -sa_mmu_cache_ops (ARMul_State * state, ARMword instr, ARMword value) -{ - int CRm, OPC_2; - - CRm = BITS (0, 3); - OPC_2 = BITS (5, 7); - - if (OPC_2 == 0 && CRm == 7) { - mmu_cache_invalidate_all (state, I_CACHE ()); - mmu_cache_invalidate_all (state, MAIN_D_CACHE ()); - mmu_cache_invalidate_all (state, MINI_D_CACHE ()); - return; - } - - if (OPC_2 == 0 && CRm == 5) { - mmu_cache_invalidate_all (state, I_CACHE ()); - return; - } - - if (OPC_2 == 0 && CRm == 6) { - mmu_cache_invalidate_all (state, MAIN_D_CACHE ()); - mmu_cache_invalidate_all (state, MINI_D_CACHE ()); - return; - } - - if (OPC_2 == 1 && CRm == 6) { - mmu_cache_invalidate (state, MAIN_D_CACHE (), value); - mmu_cache_invalidate (state, MINI_D_CACHE (), value); - return; - } - - if (OPC_2 == 1 && CRm == 0xa) { - mmu_cache_clean (state, MAIN_D_CACHE (), value); - mmu_cache_clean (state, MINI_D_CACHE (), value); - return; - } - - if (OPC_2 == 4 && CRm == 0xa) { - mmu_wb_drain_all (state, WB ()); - return; - } - ERROR_LOG(ARM11, "Unknow OPC_2 = %x CRm = %x\n", OPC_2, CRm); -} - -static void -sa_mmu_tlb_ops (ARMul_State * state, ARMword instr, ARMword value) -{ - int CRm, OPC_2; - - CRm = BITS (0, 3); - OPC_2 = BITS (5, 7); - - - if (OPC_2 == 0 && CRm == 0x7) { - mmu_tlb_invalidate_all (state, I_TLB ()); - mmu_tlb_invalidate_all (state, D_TLB ()); - return; - } - - if (OPC_2 == 0 && CRm == 0x5) { - mmu_tlb_invalidate_all (state, I_TLB ()); - return; - } - - if (OPC_2 == 0 && CRm == 0x6) { - mmu_tlb_invalidate_all (state, D_TLB ()); - return; - } - - if (OPC_2 == 1 && CRm == 0x6) { - mmu_tlb_invalidate_entry (state, D_TLB (), value); - return; - } - - ERROR_LOG(ARM11, "Unknow OPC_2 = %x CRm = %x\n", OPC_2, CRm); -} - -static void -sa_mmu_rb_ops (ARMul_State * state, ARMword instr, ARMword value) -{ - int CRm, OPC_2; - - CRm = BITS (0, 3); - OPC_2 = BITS (5, 7); - - if (OPC_2 == 0x0 && CRm == 0x0) { - mmu_rb_invalidate_all (RB ()); - return; - } - - if (OPC_2 == 0x2) { - int idx = CRm & 0x3; - int type = ((CRm >> 2) & 0x3) + 1; - - if ((idx < 4) && (type < 4)) - mmu_rb_load (state, RB (), idx, type, value); - return; - } - - if ((OPC_2 == 1) && (CRm < 4)) { - mmu_rb_invalidate_entry (RB (), CRm); - return; - } - - ERROR_LOG(ARM11, "Unknow OPC_2 = %x CRm = %x\n", OPC_2, CRm); -} - -static ARMword -sa_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value) -{ - mmu_regnum_t creg = (mmu_regnum_t)(BITS (16, 19) & 15); - if (!strncmp (state->cpu->cpu_arch_name, "armv4", 5)) { - switch (creg) { - case MMU_CONTROL: -// printf("mmu_mcr wrote CONTROL "); - state->mmu.control = (value | 0x70) & 0xFFFD; - break; - case MMU_TRANSLATION_TABLE_BASE: -// printf("mmu_mcr wrote TTB "); - state->mmu.translation_table_base = - value & 0xFFFFC000; - break; - case MMU_DOMAIN_ACCESS_CONTROL: -// printf("mmu_mcr wrote DACR "); - state->mmu.domain_access_control = value; - break; - - case MMU_FAULT_STATUS: - state->mmu.fault_status = value & 0xFF; - break; - case MMU_FAULT_ADDRESS: - state->mmu.fault_address = value; - break; - - case MMU_CACHE_OPS: - sa_mmu_cache_ops (state, instr, value); - break; - case MMU_TLB_OPS: - sa_mmu_tlb_ops (state, instr, value); - break; - case MMU_SA_RB_OPS: - sa_mmu_rb_ops (state, instr, value); - break; - case MMU_SA_DEBUG: - break; - case MMU_SA_CP15_R15: - break; - case MMU_PID: - //2004-06-06 lyh, bug provided by wen ye wenye@cs.ucsb.edu - state->mmu.process_id = value & 0x7e000000; - break; - - default: - printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg); - break; - } - } - return 0; -} - -//teawater add for arm2x86 2005.06.24------------------------------------------- -static int -sa_mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr) -{ - fault_t fault; - tlb_entry_t *tlb; - - virt_addr = mmu_pid_va_map (virt_addr); - if (MMU_Enabled) { - - /*align check */ - if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } - else - virt_addr &= ~(WORD_SIZE - 1); - - /*translate tlb */ - fault = translate (state, virt_addr, I_TLB (), &tlb); - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - return fault; - } - - /*check access */ - fault = check_access (state, virt_addr, tlb, 1); - if (fault) { - DEBUG_LOG(ARM11, "check_fault\n"); - return fault; - } - } - - if (MMU_Disabled) { - *phys_addr = virt_addr; - } - else { - *phys_addr = tlb_va_to_pa (tlb, virt_addr); - } - - return (0); -} - -//AJ2D-------------------------------------------------------------------------- - -/*sa mmu_ops_t*/ -mmu_ops_t sa_mmu_ops = { - sa_mmu_init, - sa_mmu_exit, - sa_mmu_read_byte, - sa_mmu_write_byte, - sa_mmu_read_halfword, - sa_mmu_write_halfword, - sa_mmu_read_word, - sa_mmu_write_word, - sa_mmu_load_instr, - sa_mmu_mcr, - sa_mmu_mrc, -//teawater add for arm2x86 2005.06.24------------------------------------------- - sa_mmu_v2p_dbct, -//AJ2D-------------------------------------------------------------------------- -}; diff --git a/src/core/arm/interpreter/mmu/sa_mmu.h b/src/core/arm/interpreter/mmu/sa_mmu.h deleted file mode 100644 index 64b1c5470..000000000 --- a/src/core/arm/interpreter/mmu/sa_mmu.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - sa_mmu.h - StrongARM Memory Management Unit emulation. - ARMulator extensions for SkyEye. - <lyhost@263.net> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef _SA_MMU_H_ -#define _SA_MMU_H_ - - -/** - * The interface of read data from bus - */ -int bus_read(short size, int addr, uint32_t * value); - -/** - * The interface of write data from bus - */ -int bus_write(short size, int addr, uint32_t value); - - -typedef struct sa_mmu_s -{ - tlb_s i_tlb; - cache_s i_cache; - - tlb_s d_tlb; - cache_s main_d_cache; - cache_s mini_d_cache; - rb_s rb_t; - wb_s wb_t; -} sa_mmu_t; - -#define I_TLB() (&state->mmu.u.sa_mmu.i_tlb) -#define I_CACHE() (&state->mmu.u.sa_mmu.i_cache) - -#define D_TLB() (&state->mmu.u.sa_mmu.d_tlb) -#define MAIN_D_CACHE() (&state->mmu.u.sa_mmu.main_d_cache) -#define MINI_D_CACHE() (&state->mmu.u.sa_mmu.mini_d_cache) -#define WB() (&state->mmu.u.sa_mmu.wb_t) -#define RB() (&state->mmu.u.sa_mmu.rb_t) - -extern mmu_ops_t sa_mmu_ops; -#endif /*_SA_MMU_H_*/ diff --git a/src/core/arm/interpreter/mmu/tlb.cpp b/src/core/arm/interpreter/mmu/tlb.cpp deleted file mode 100644 index 88c2a8bc5..000000000 --- a/src/core/arm/interpreter/mmu/tlb.cpp +++ /dev/null @@ -1,307 +0,0 @@ -#include <assert.h> - -#include "core/arm/skyeye_common/armdefs.h" - -ARMword tlb_masks[] = { - 0x00000000, /* TLB_INVALID */ - 0xFFFFF000, /* TLB_SMALLPAGE */ - 0xFFFF0000, /* TLB_LARGEPAGE */ - 0xFFF00000, /* TLB_SECTION */ - 0xFFFFF000, /*TLB_ESMALLPAGE, have TEX attirbute, only for XScale */ - 0xFFFFFC00 /* TLB_TINYPAGE */ -}; - -/* This function encodes table 8-2 Interpreting AP bits, - returning non-zero if access is allowed. */ -static int -check_perms (ARMul_State * state, int ap, int read) -{ - int s, r, user; - - s = state->mmu.control & CONTROL_SYSTEM; - r = state->mmu.control & CONTROL_ROM; - //chy 2006-02-15 , should consider system mode, don't conside 26bit mode - user = (state->Mode == USER32MODE) || (state->Mode == USER26MODE) || (state->Mode == SYSTEM32MODE); - - switch (ap) { - case 0: - return read && ((s && !user) || r); - case 1: - return !user; - case 2: - return read || !user; - case 3: - return 1; - } - return 0; -} - -fault_t -check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb, - int read) -{ - int access; - - state->mmu.last_domain = tlb->domain; - access = (state->mmu.domain_access_control >> (tlb->domain * 2)) & 3; - if ((access == 0) || (access == 2)) { - /* It's unclear from the documentation whether this - should always raise a section domain fault, or if - it should be a page domain fault in the case of an - L1 that describes a page table. In the ARM710T - datasheets, "Figure 8-9: Sequence for checking faults" - seems to indicate the former, while "Table 8-4: Priority - encoding of fault status" gives a value for FS[3210] in - the event of a domain fault for a page. Hmm. */ - return SECTION_DOMAIN_FAULT; - } - if (access == 1) { - /* client access - check perms */ - int subpage, ap; - - switch (tlb->mapping) { - /*ks 2004-05-09 - * only for XScale - * Extend Small Page(ESP) Format - * 31-12 bits the base addr of ESP - * 11-10 bits SBZ - * 9-6 bits TEX - * 5-4 bits AP - * 3 bit C - * 2 bit B - * 1-0 bits 11 - * */ - case TLB_ESMALLPAGE: //xj - subpage = 0; - //printf("TLB_ESMALLPAGE virt_addr=0x%x \n",virt_addr ); - break; - - case TLB_TINYPAGE: - subpage = 0; - //printf("TLB_TINYPAGE virt_addr=0x%x \n",virt_addr ); - break; - - case TLB_SMALLPAGE: - subpage = (virt_addr >> 10) & 3; - break; - case TLB_LARGEPAGE: - subpage = (virt_addr >> 14) & 3; - break; - case TLB_SECTION: - subpage = 3; - break; - default: - assert (0); - subpage = 0; /* cleans a warning */ - } - ap = (tlb->perms >> (subpage * 2 + 4)) & 3; - if (!check_perms (state, ap, read)) { - if (tlb->mapping == TLB_SECTION) { - return SECTION_PERMISSION_FAULT; - } - else { - return SUBPAGE_PERMISSION_FAULT; - } - } - } - else { /* access == 3 */ - /* manager access - don't check perms */ - } - return NO_FAULT; -} - -fault_t -translate (ARMul_State * state, ARMword virt_addr, tlb_s * tlb_t, - tlb_entry_t ** tlb) -{ - *tlb = mmu_tlb_search (state, tlb_t, virt_addr); - if (!*tlb) { - /* walk the translation tables */ - ARMword l1addr, l1desc; - tlb_entry_t entry; - - l1addr = state->mmu.translation_table_base & 0xFFFFC000; - l1addr = (l1addr | (virt_addr >> 18)) & ~3; - //l1desc = mem_read_word (state, l1addr); - bus_read(32, l1addr, &l1desc); - switch (l1desc & 3) { - case 0: - /* - * according to Figure 3-9 Sequence for checking faults in arm manual, - * section translation fault should be returned here. - */ - { - return SECTION_TRANSLATION_FAULT; - } - case 3: - /* fine page table */ - // dcl 2006-01-08 - { - ARMword l2addr, l2desc; - - l2addr = l1desc & 0xFFFFF000; - l2addr = (l2addr | - ((virt_addr & 0x000FFC00) >> 8)) & - ~3; - //l2desc = mem_read_word (state, l2addr); - bus_read(32, l2addr, &l2desc); - - entry.virt_addr = virt_addr; - entry.phys_addr = l2desc; - entry.perms = l2desc & 0x00000FFC; - entry.domain = (l1desc >> 5) & 0x0000000F; - switch (l2desc & 3) { - case 0: - state->mmu.last_domain = entry.domain; - return PAGE_TRANSLATION_FAULT; - case 3: - entry.mapping = TLB_TINYPAGE; - break; - case 1: - // this is untested - entry.mapping = TLB_LARGEPAGE; - break; - case 2: - // this is untested - entry.mapping = TLB_SMALLPAGE; - break; - } - } - break; - case 1: - /* coarse page table */ - { - ARMword l2addr, l2desc; - - l2addr = l1desc & 0xFFFFFC00; - l2addr = (l2addr | - ((virt_addr & 0x000FF000) >> 10)) & - ~3; - //l2desc = mem_read_word (state, l2addr); - bus_read(32, l2addr, &l2desc); - - entry.virt_addr = virt_addr; - entry.phys_addr = l2desc; - entry.perms = l2desc & 0x00000FFC; - entry.domain = (l1desc >> 5) & 0x0000000F; - //printf("SKYEYE:PAGE virt_addr = %x,l1desc=%x,phys_addr=%x\n",virt_addr,l1desc,entry.phys_addr); - //chy 2003-09-02 for xscale - switch (l2desc & 3) { - case 0: - state->mmu.last_domain = entry.domain; - return PAGE_TRANSLATION_FAULT; - case 3: - if (!state->is_XScale) { - state->mmu.last_domain = - entry.domain; - return PAGE_TRANSLATION_FAULT; - }; - //ks 2004-05-09 xscale shold use Extend Small Page - //entry.mapping = TLB_SMALLPAGE; - entry.mapping = TLB_ESMALLPAGE; //xj - break; - case 1: - entry.mapping = TLB_LARGEPAGE; - break; - case 2: - entry.mapping = TLB_SMALLPAGE; - break; - } - } - break; - case 2: - /* section */ - //printf("SKYEYE:WARNING: not implement section mapping incompletely\n"); - //printf("SKYEYE:SECTION virt_addr = %x,l1desc=%x\n",virt_addr,l1desc); - //return SECTION_DOMAIN_FAULT; - //#if 0 - entry.virt_addr = virt_addr; - entry.phys_addr = l1desc; - entry.perms = l1desc & 0x00000C0C; - entry.domain = (l1desc >> 5) & 0x0000000F; - entry.mapping = TLB_SECTION; - break; - //#endif - } - entry.virt_addr &= tlb_masks[entry.mapping]; - entry.phys_addr &= tlb_masks[entry.mapping]; - - /* place entry in the tlb */ - *tlb = &tlb_t->entrys[tlb_t->cycle]; - tlb_t->cycle = (tlb_t->cycle + 1) % tlb_t->num; - **tlb = entry; - } - state->mmu.last_domain = (*tlb)->domain; - return NO_FAULT; -} - -int -mmu_tlb_init (tlb_s * tlb_t, int num) -{ - tlb_entry_t *e; - int i; - - e = (tlb_entry_t *) malloc (sizeof (*e) * num); - if (e == NULL) { - ERROR_LOG(ARM11, "malloc size %d\n", sizeof (*e) * num); - goto tlb_malloc_error; - } - tlb_t->entrys = e; - for (i = 0; i < num; i++, e++) - e->mapping = TLB_INVALID; - tlb_t->cycle = 0; - tlb_t->num = num; - return 0; - - tlb_malloc_error: - return -1; -} - -void -mmu_tlb_exit (tlb_s * tlb_t) -{ - free (tlb_t->entrys); -}; - -void -mmu_tlb_invalidate_all (ARMul_State * state, tlb_s * tlb_t) -{ - int entry; - - for (entry = 0; entry < tlb_t->num; entry++) { - tlb_t->entrys[entry].mapping = TLB_INVALID; - } - tlb_t->cycle = 0; -} - -void -mmu_tlb_invalidate_entry (ARMul_State * state, tlb_s * tlb_t, ARMword addr) -{ - tlb_entry_t *tlb; - - tlb = mmu_tlb_search (state, tlb_t, addr); - if (tlb) { - tlb->mapping = TLB_INVALID; - } -} - -tlb_entry_t * -mmu_tlb_search (ARMul_State * state, tlb_s * tlb_t, ARMword virt_addr) -{ - int entry; - - for (entry = 0; entry < tlb_t->num; entry++) { - tlb_entry_t *tlb; - ARMword mask; - - tlb = &(tlb_t->entrys[entry]); - if (tlb->mapping == TLB_INVALID) { - continue; - } - mask = tlb_masks[tlb->mapping]; - if ((virt_addr & mask) == (tlb->virt_addr & mask)) { - return tlb; - } - } - return NULL; -} diff --git a/src/core/arm/interpreter/mmu/tlb.h b/src/core/arm/interpreter/mmu/tlb.h deleted file mode 100644 index 40856567b..000000000 --- a/src/core/arm/interpreter/mmu/tlb.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _MMU_TLB_H_ -#define _MMU_TLB_H_ - -typedef enum tlb_mapping_t -{ - TLB_INVALID = 0, - TLB_SMALLPAGE = 1, - TLB_LARGEPAGE = 2, - TLB_SECTION = 3, - TLB_ESMALLPAGE = 4, - TLB_TINYPAGE = 5 -} tlb_mapping_t; - -extern ARMword tlb_masks[]; - -/* Permissions bits in a TLB entry: - * - * 31 12 11 10 9 8 7 6 5 4 3 2 1 0 - * +-------------+-----+-----+-----+-----+---+---+-------+ - * Page:| | ap3 | ap2 | ap1 | ap0 | C | B | | - * +-------------+-----+-----+-----+-----+---+---+-------+ - * - * 31 12 11 10 9 4 3 2 1 0 - * +-------------+-----+-----------------+---+---+-------+ - * Section: | | AP | | C | B | | - * +-------------+-----+-----------------+---+---+-------+ - */ - -/* -section: - section base address [31:20] - AP - table 8-2, page 8-8 - domain - C,B - -page: - page base address [31:16] or [31:12] - ap[3:0] - domain (from L1) - C,B -*/ - - -typedef struct tlb_entry_t -{ - ARMword virt_addr; - ARMword phys_addr; - ARMword perms; - ARMword domain; - tlb_mapping_t mapping; -} tlb_entry_t; - -typedef struct tlb_s -{ - int num; /*num of tlb entry */ - int cycle; /*current tlb cycle */ - tlb_entry_t *entrys; -} tlb_s; - - -#define tlb_c_flag(tlb) \ - ((tlb)->perms & 0x8) -#define tlb_b_flag(tlb) \ - ((tlb)->perms & 0x4) - -#define tlb_va_to_pa(tlb, va) ((tlb->phys_addr & tlb_masks[tlb->mapping]) | (va & ~tlb_masks[tlb->mapping])) -fault_t -check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb, - int read); - -fault_t -translate (ARMul_State * state, ARMword virt_addr, tlb_s * tlb_t, - tlb_entry_t ** tlb); - -int mmu_tlb_init (tlb_s * tlb_t, int num); - -void mmu_tlb_exit (tlb_s * tlb_t); - -void mmu_tlb_invalidate_all (ARMul_State * state, tlb_s * tlb_t); - -void -mmu_tlb_invalidate_entry (ARMul_State * state, tlb_s * tlb_t, ARMword addr); - -tlb_entry_t *mmu_tlb_search (ARMul_State * state, tlb_s * tlb_t, - ARMword virt_addr); - -#endif /*_MMU_TLB_H_*/ diff --git a/src/core/arm/interpreter/mmu/wb.cpp b/src/core/arm/interpreter/mmu/wb.cpp deleted file mode 100644 index 5ddda41ee..000000000 --- a/src/core/arm/interpreter/mmu/wb.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include "core/arm/skyeye_common/armdefs.h" - -/* wb_init - * @wb_t :wb_t to init - * @num :num of entrys - * @nb :num of byte of each entry - * - * $ -1:error - * 0:ok - * */ -int -mmu_wb_init (wb_s * wb_t, int num, int nb) -{ - int i; - wb_entry_t *entrys, *wb; - - entrys = (wb_entry_t *) malloc (sizeof (*entrys) * num); - if (entrys == NULL) { - ERROR_LOG(ARM11, "malloc size %d\n", sizeof (*entrys) * num); - goto entrys_malloc_error; - } - - for (wb = entrys, i = 0; i < num; i++, wb++) { - /*chy 2004-06-06, fix bug found by wenye@cs.ucsb.edu */ - //wb->data = (ARMword *)malloc(sizeof(ARMword) * nb); - wb->data = (ARMbyte *) malloc (nb); - if (wb->data == NULL) { - ERROR_LOG(ARM11, "malloc size of %d\n", nb); - goto data_malloc_error; - } - - }; - - wb_t->first = wb_t->last = wb_t->used = 0; - wb_t->num = num; - wb_t->nb = nb; - wb_t->entrys = entrys; - return 0; - - data_malloc_error: - while (--i >= 0) - free (entrys[i].data); - free (entrys); - entrys_malloc_error: - return -1; -}; - -/* wb_exit - * @wb_t :wb_t to exit - * */ -void -mmu_wb_exit (wb_s * wb_t) -{ - int i; - wb_entry_t *wb; - - wb = wb_t->entrys; - for (i = 0; i < wb_t->num; i++, wb++) { - free (wb->data); - } - free (wb_t->entrys); -}; - -/* wb_write_words :put words in Write Buffer - * @state: ARMul_State - * @wb_t: write buffer - * @pa: physical address - * @data: data ptr - * @n number of word to write - * - * Note: write buffer merge is not implemented, can be done late - * */ -void -mmu_wb_write_bytes (ARMul_State * state, wb_s * wb_t, ARMword pa, - ARMbyte * data, int n) -{ - int i; - wb_entry_t *wb; - - while (n) { - if (wb_t->num == wb_t->used) { - /*clean the last wb entry */ - ARMword t; - - wb = &wb_t->entrys[wb_t->last]; - t = wb->pa; - for (i = 0; i < wb->nb; i++) { - //mem_write_byte (state, t, wb->data[i]); - bus_write(8, t, wb->data[i]); - //t += WORD_SIZE; - t++; - } - wb_t->last++; - if (wb_t->last == wb_t->num) - wb_t->last = 0; - wb_t->used--; - } - - wb = &wb_t->entrys[wb_t->first]; - i = (n < wb_t->nb) ? n : wb_t->nb; - - wb->pa = pa; - //pa += i << WORD_SHT; - pa += i; - - wb->nb = i; - //memcpy(wb->data, data, i << WORD_SHT); - memcpy (wb->data, data, i); - data += i; - n -= i; - wb_t->first++; - if (wb_t->first == wb_t->num) - wb_t->first = 0; - wb_t->used++; - }; -//teawater add for set_dirty fflash cache function 2005.07.18------------------- -#ifdef DBCT - if (!skyeye_config.no_dbct) { - tb_setdirty (state, pa, NULL); - } -#endif -//AJ2D-------------------------------------------------------------------------- -} - -/* wb_drain_all - * @wb_t wb_t to drain - * */ -void -mmu_wb_drain_all (ARMul_State * state, wb_s * wb_t) -{ - ARMword pa; - wb_entry_t *wb; - int i; - - while (wb_t->used) { - wb = &wb_t->entrys[wb_t->last]; - pa = wb->pa; - for (i = 0; i < wb->nb; i++) { - //mem_write_byte (state, pa, wb->data[i]); - bus_write(8, pa, wb->data[i]); - //pa += WORD_SIZE; - pa++; - } - wb_t->last++; - if (wb_t->last == wb_t->num) - wb_t->last = 0; - wb_t->used--; - }; -} diff --git a/src/core/arm/interpreter/mmu/wb.h b/src/core/arm/interpreter/mmu/wb.h deleted file mode 100644 index 8fb7de946..000000000 --- a/src/core/arm/interpreter/mmu/wb.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef _MMU_WB_H_ -#define _MMU_WB_H_ - -typedef struct wb_entry_s -{ - ARMword pa; //phy_addr - ARMbyte *data; //data - int nb; //number byte to write -} wb_entry_t; - -typedef struct wb_s -{ - int num; //number of wb_entry - int nb; //number of byte of each entry - int first; // - int last; // - int used; // - wb_entry_t *entrys; -} wb_s; - -typedef struct wb_desc_s -{ - int num; - int nb; -} wb_desc_t; - -/* wb_init - * @wb_t :wb_t to init - * @num :num of entrys - * @nw :num of word of each entry - * - * $ -1:error - * 0:ok - * */ -int mmu_wb_init (wb_s * wb_t, int num, int nb); - - -/* wb_exit - * @wb_t :wb_t to exit - * */ -void mmu_wb_exit (wb_s * wb); - - -/* wb_write_bytes :put bytess in Write Buffer - * @state: ARMul_State - * @wb_t: write buffer - * @pa: physical address - * @data: data ptr - * @n number of byte to write - * - * Note: write buffer merge is not implemented, can be done late - * */ -void -mmu_wb_write_bytess (ARMul_State * state, wb_s * wb_t, ARMword pa, - ARMbyte * data, int n); - - -/* wb_drain_all - * @wb_t wb_t to drain - * */ -void mmu_wb_drain_all (ARMul_State * state, wb_s * wb_t); - -#endif /*_MMU_WB_H_*/ diff --git a/src/core/arm/interpreter/mmu/xscale_copro.cpp b/src/core/arm/interpreter/mmu/xscale_copro.cpp deleted file mode 100644 index cf91fd933..000000000 --- a/src/core/arm/interpreter/mmu/xscale_copro.cpp +++ /dev/null @@ -1,1391 +0,0 @@ -/* - armmmu.c - Memory Management Unit emulation. - ARMulator extensions for the ARM7100 family. - Copyright (C) 1999 Ben Williamson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include <assert.h> -#include <string.h> - -#include "core/arm/skyeye_common/armdefs.h" -#include "core/arm/skyeye_common/armemu.h" - -/*#include "pxa.h" */ - -/* chy 2005-09-19 */ - -/* extern pxa270_io_t pxa270_io; */ -/* chy 2005-09-19 -----end */ - -typedef struct xscale_mmu_desc_s -{ - int i_tlb; - cache_desc_t i_cache; - - int d_tlb; - cache_desc_t main_d_cache; - cache_desc_t mini_d_cache; - //int rb; xscale has no read buffer - wb_desc_t wb; -} xscale_mmu_desc_t; - -static xscale_mmu_desc_t pxa_mmu_desc = { - 32, - {32, 32, 32, CACHE_WRITE_BACK}, - - 32, - {32, 32, 32, CACHE_WRITE_BACK}, - {32, 2, 8, CACHE_WRITE_BACK}, - {8, 16}, //for byte size, -}; - -//chy 2005-09-19 for cp6 -#define CR0_ICIP 0 -#define CR1_ICMR 1 -//chy 2005-09-19 ---end -//----------- for cp14----------------- -#define CCLKCFG 6 -#define PWRMODE 7 -typedef struct xscale_cp14_reg_s -{ - unsigned cclkcfg; //reg6 - unsigned pwrmode; //reg7 -} xscale_cp14_reg_s; - -xscale_cp14_reg_s pxa_cp14_regs; - -//-------------------------------------- - -static fault_t xscale_mmu_write (ARMul_State * state, ARMword va, - ARMword data, ARMword datatype); -static fault_t xscale_mmu_read (ARMul_State * state, ARMword va, - ARMword * data, ARMword datatype); - -ARMword xscale_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value); -ARMword xscale_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value); - - -/* jeff add 2010.9.26 for pxa270 cp6*/ -#define PXA270_ICMR 0x40D00004 -#define PXA270_ICPR 0x40D00010 -#define PXA270_ICLR 0x40D00008 -//chy 2005-09-19 for xscale pxa27x cp6 -unsigned -xscale_cp6_mrc (ARMul_State * state, unsigned type, ARMword instr, - ARMword * data) -{ - unsigned opcode_2 = BITS (5, 7); - unsigned CRm = BITS (0, 3); - unsigned reg = BITS (16, 19); - unsigned result; - - //printf("SKYEYE: xscale_cp6_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,state->Reg[15], instr); - - switch (reg) { - case CR0_ICIP: { // cp 6 reg 0 - //printf("cp6_mrc cr0 ICIP \n"); - /* *data = (pxa270_io.icmr & pxa270_io.icpr) & ~pxa270_io.iclr; */ - /* use bus_read get the pxa270 machine registers 2010.9.26 jeff*/ - int icmr, icpr, iclr; - bus_read(32, PXA270_ICMR, (uint32_t*)&icmr); - bus_read(32, PXA270_ICPR, (uint32_t*)&icpr); - bus_read(32, PXA270_ICLR, (uint32_t*)&iclr); - *data = (icmr & icpr) & ~iclr; - } - break; - case CR1_ICMR: { // cp 6 reg 1 - //printf("cp6_mrc cr1 ICMR\n"); - /* *data = pxa270_io.icmr; */ - int icmr; - /* use bus_read get the pxa270 machine registers 2010.9.26 jeff*/ - bus_read(32, PXA270_ICMR, (uint32_t*)&icmr); - *data = icmr; - } - break; - default: - *data = 0; - printf ("SKYEYE:cp6_mrc unknown cp6 regs!!!!!!\n"); - printf ("SKYEYE: xscale_cp6_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n", opcode_2, CRm, reg, state->Reg[15], instr); - break; - } - return 0; -} - -//chy 2005-09-19 end -//xscale cp13 ---------------------------------------------------- -unsigned -xscale_cp13_init (ARMul_State * state) -{ - //printf("SKYEYE: xscale_cp13_init: begin\n"); - return 0; -} - -unsigned -xscale_cp13_exit (ARMul_State * state) -{ - //printf("SKYEYE: xscale_cp13_exit: begin\n"); - return 0; -} - -unsigned -xscale_cp13_ldc (ARMul_State * state, unsigned type, ARMword instr, - ARMword data) -{ - printf ("SKYEYE: xscale_cp13_ldc: ERROR isn't existed,"); - SKYEYE_OUTREGS (stderr); - fprintf (stderr, "\n"); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} - -unsigned -xscale_cp13_stc (ARMul_State * state, unsigned type, ARMword instr, - ARMword * data) -{ - printf ("SKYEYE: xscale_cp13_stc: ERROR isn't existed,"); - SKYEYE_OUTREGS (stderr); - fprintf (stderr, "\n"); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} - -unsigned -xscale_cp13_mrc (ARMul_State * state, unsigned type, ARMword instr, - ARMword * data) -{ - printf ("SKYEYE: xscale_cp13_mrc: ERROR isn't existed,"); - SKYEYE_OUTREGS (stderr); - fprintf (stderr, "\n"); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} - -unsigned -xscale_cp13_mcr (ARMul_State * state, unsigned type, ARMword instr, - ARMword data) -{ - printf ("SKYEYE: xscale_cp13_mcr: ERROR isn't existed,"); - SKYEYE_OUTREGS (stderr); - fprintf (stderr, "\n"); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} - -unsigned -xscale_cp13_cdp (ARMul_State * state, unsigned type, ARMword instr) -{ - printf ("SKYEYE: xscale_cp13_cdp: ERROR isn't existed,"); - SKYEYE_OUTREGS (stderr); - fprintf (stderr, "\n"); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} - -unsigned -xscale_cp13_read_reg (ARMul_State * state, unsigned reg, ARMword * data) -{ - printf ("SKYEYE: xscale_cp13_read_reg: ERROR isn't existed,"); - SKYEYE_OUTREGS (stderr); - fprintf (stderr, "\n"); - return 0; - //exit(-1); -} - -unsigned -xscale_cp13_write_reg (ARMul_State * state, unsigned reg, ARMword data) -{ - printf ("SKYEYE: xscale_cp13_write_reg: ERROR isn't existed,"); - SKYEYE_OUTREGS (stderr); - fprintf (stderr, "\n"); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} - -//------------------------------------------------------------------ -//xscale cp14 ---------------------------------------------------- -unsigned -xscale_cp14_init (ARMul_State * state) -{ - //printf("SKYEYE: xscale_cp14_init: begin\n"); - pxa_cp14_regs.cclkcfg = 0; - pxa_cp14_regs.pwrmode = 0; - return 0; -} - -unsigned -xscale_cp14_exit (ARMul_State * state) -{ - //printf("SKYEYE: xscale_cp14_exit: begin\n"); - return 0; -} - -unsigned -xscale_cp14_ldc (ARMul_State * state, unsigned type, ARMword instr, - ARMword data) -{ - printf ("SKYEYE: xscale_cp14_ldc: ERROR isn't existed, reg15 0x%x\n", - state->Reg[15]); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} - -unsigned -xscale_cp14_stc (ARMul_State * state, unsigned type, ARMword instr, - ARMword * data) -{ - printf ("SKYEYE: xscale_cp14_stc: ERROR isn't existed, reg15 0x%x\n", - state->Reg[15]); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} - -unsigned -xscale_cp14_mrc (ARMul_State * state, unsigned type, ARMword instr, - ARMword * data) -{ - unsigned opcode_2 = BITS (5, 7); - unsigned CRm = BITS (0, 3); - unsigned reg = BITS (16, 19); - unsigned result; - - //printf("SKYEYE: xscale_cp14_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\ - state->Reg[15], instr); - - switch (reg) { - case CCLKCFG: // cp 14 reg 6 - //printf("cp14_mrc cclkcfg \n"); - *data = pxa_cp14_regs.cclkcfg; - break; - case PWRMODE: // cp 14 reg 7 - //printf("cp14_mrc pwrmode \n"); - *data = pxa_cp14_regs.pwrmode; - break; - default: - *data = 0; - printf ("SKYEYE:cp14_mrc unknown cp14 regs!!!!!!\n"); - break; - } - return 0; -} -unsigned xscale_cp14_mcr (ARMul_State * state, unsigned type, ARMword instr, - ARMword data) -{ - unsigned opcode_2 = BITS (5, 7); - unsigned CRm = BITS (0, 3); - unsigned reg = BITS (16, 19); - unsigned result; - - //printf("SKYEYE: xscale_cp14_mcr:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\ - state->Reg[15], instr); - - switch (reg) { - case CCLKCFG: // cp 14 reg 6 - //printf("cp14_mcr cclkcfg \n"); - pxa_cp14_regs.cclkcfg = data & 0xf; - break; - case PWRMODE: // cp 14 reg 7 - //printf("cp14_mcr pwrmode \n"); - pxa_cp14_regs.pwrmode = data & 0x3; - break; - default:printf ("SKYEYE: cp14_mcr unknown cp14 regs!!!!!!\n"); - break; - } - return 0; -} -unsigned xscale_cp14_cdp (ARMul_State * state, unsigned type, ARMword instr) -{ - printf ("SKYEYE: xscale_cp14_cdp: ERROR isn't existed, reg15 0x%x\n", - state->Reg[15]); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} -unsigned xscale_cp14_read_reg (ARMul_State * state, unsigned reg, - ARMword * data) -{ - printf ("SKYEYE: xscale_cp14_read_reg: ERROR isn't existed, reg15 0x%x\n", state->Reg[15]); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - return 0; //No matter return value, only for compiler. -} -unsigned xscale_cp14_write_reg (ARMul_State * state, unsigned reg, - ARMword data) -{ - printf ("SKYEYE: xscale_cp14_write_reg: ERROR isn't existed, reg15 0x%x\n", state->Reg[15]); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - - return 0; //No matter return value, only for compiler. -} - -//------------------------------------------------------------------ -//cp15 ------------------------------------- -unsigned xscale_cp15_ldc (ARMul_State * state, unsigned type, ARMword instr, - ARMword data) -{ - printf ("SKYEYE: xscale_cp15_ldc: ERROR isn't existed\n"); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - - return 0; //No matter return value, only for compiler. -} -unsigned xscale_cp15_stc (ARMul_State * state, unsigned type, ARMword instr, - ARMword * data) -{ - printf ("SKYEYE: xscale_cp15_stc: ERROR isn't existed\n"); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - - return 0; //No matter return value, only for compiler. -} -unsigned xscale_cp15_cdp (ARMul_State * state, unsigned type, ARMword instr) -{ - printf ("SKYEYE: xscale_cp15_cdp: ERROR isn't existed\n"); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - - return 0; //No matter return value, only for compiler. -} -unsigned xscale_cp15_read_reg (ARMul_State * state, unsigned reg, - ARMword * data) -{ -//chy 2003-09-03: for xsacle_cp15_cp_access_allowed - if (reg == 15) { - *data = state->mmu.copro_access; - //printf("SKYEYE: xscale_cp15_read_reg: reg 0x%x,data %x\n",reg,*data); - return 0; - } - printf ("SKYEYE: xscale_cp15_read_reg: reg 0x%x, ERROR isn't existed\n", reg); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - - return 0; //No matter return value, only for compiler. -} - -//chy 2003-09-03 used by macro CP_ACCESS_ALLOWED in armemu.h -unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg, - unsigned cpnum) -{ - unsigned data; - - xscale_cp15_read_reg (state, reg, &data); - //printf("SKYEYE: cp15_cp_access_allowed data %x, cpnum %x, result %x\n", data, cpnum, (data & 1<<cpnum)); - if (data & 1 << cpnum) - return 1; - else - return 0; -} - -unsigned xscale_cp15_write_reg (ARMul_State * state, unsigned reg, - ARMword value) -{ - switch (reg) { - case MMU_FAULT_STATUS: - //printf("SKYEYE:cp15_write_reg wrote FS val 0x%x \n",value); - state->mmu.fault_status = value & 0x6FF; - break; - case MMU_FAULT_ADDRESS: - //printf("SKYEYE:cp15_write_reg wrote FA val 0x%x \n",value); - state->mmu.fault_address = value; - break; - default: - printf ("SKYEYE: xscale_cp15_write_reg: reg 0x%x R15 %x ERROR isn't existed\n", reg, state->Reg[15]); - SKYEYE_OUTREGS (stderr); - // skyeye_exit (-1); - } - return 0; -} - -unsigned -xscale_cp15_init (ARMul_State * state) -{ - xscale_mmu_desc_t *desc; - cache_desc_t *c_desc; - - state->mmu.control = 0; - state->mmu.translation_table_base = 0xDEADC0DE; - state->mmu.domain_access_control = 0xDEADC0DE; - state->mmu.fault_status = 0; - state->mmu.fault_address = 0; - state->mmu.process_id = 0; - state->mmu.cache_type = 0xB1AA1AA; //0000 1011 0001 1010 1010 0001 1010 1010 - state->mmu.aux_control = 0; - - desc = &pxa_mmu_desc; - - if (mmu_tlb_init (I_TLB (), desc->i_tlb)) { - ERROR_LOG(ARM11, "i_tlb init %d\n", -1); - goto i_tlb_init_error; - } - - c_desc = &desc->i_cache; - if (mmu_cache_init (I_CACHE (), c_desc->width, c_desc->way, - c_desc->set, c_desc->w_mode)) { - ERROR_LOG(ARM11, "i_cache init %d\n", -1); - goto i_cache_init_error; - } - - if (mmu_tlb_init (D_TLB (), desc->d_tlb)) { - ERROR_LOG(ARM11, "d_tlb init %d\n", -1); - goto d_tlb_init_error; - } - - c_desc = &desc->main_d_cache; - if (mmu_cache_init (MAIN_D_CACHE (), c_desc->width, c_desc->way, - c_desc->set, c_desc->w_mode)) { - ERROR_LOG(ARM11, "main_d_cache init %d\n", -1); - goto main_d_cache_init_error; - } - - c_desc = &desc->mini_d_cache; - if (mmu_cache_init (MINI_D_CACHE (), c_desc->width, c_desc->way, - c_desc->set, c_desc->w_mode)) { - ERROR_LOG(ARM11, "mini_d_cache init %d\n", -1); - goto mini_d_cache_init_error; - } - - if (mmu_wb_init (WB (), desc->wb.num, desc->wb.nb)) { - ERROR_LOG(ARM11, "wb init %d\n", -1); - goto wb_init_error; - } -#if 0 - if (mmu_rb_init (RB (), desc->rb)) { - ERROR_LOG(ARM11, "rb init %d\n", -1); - goto rb_init_error; - } -#endif - - return 0; -#if 0 - rb_init_error: - mmu_wb_exit (WB ()); -#endif - wb_init_error: - mmu_cache_exit (MINI_D_CACHE ()); - mini_d_cache_init_error: - mmu_cache_exit (MAIN_D_CACHE ()); - main_d_cache_init_error: - mmu_tlb_exit (D_TLB ()); - d_tlb_init_error: - mmu_cache_exit (I_CACHE ()); - i_cache_init_error: - mmu_tlb_exit (I_TLB ()); - i_tlb_init_error: - return -1; -} - -unsigned -xscale_cp15_exit (ARMul_State * state) -{ - //mmu_rb_exit(RB()); - mmu_wb_exit (WB ()); - mmu_cache_exit (MINI_D_CACHE ()); - mmu_cache_exit (MAIN_D_CACHE ()); - mmu_tlb_exit (D_TLB ()); - mmu_cache_exit (I_CACHE ()); - mmu_tlb_exit (I_TLB ()); - return 0; -}; - - -static fault_t - xscale_mmu_load_instr (ARMul_State * state, ARMword va, - ARMword * instr) -{ - fault_t fault; - tlb_entry_t *tlb; - cache_line_t *cache; - int c; //cache bit - ARMword pa; //physical addr - - static int debug_count = 0; //used for debug - - DEBUG_LOG(ARM11, "va = %x\n", va); - - va = mmu_pid_va_map (va); - if (MMU_Enabled) { - /*align check */ - if ((va & (INSN_SIZE - 1)) && MMU_Aligned) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } - else - va &= ~(INSN_SIZE - 1); - - /*translate tlb */ - fault = translate (state, va, I_TLB (), &tlb); - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - return fault; - } - - /*check access */ - fault = check_access (state, va, tlb, 1); - if (fault) { - DEBUG_LOG(ARM11, "check_fault\n"); - return fault; - } - } - //chy 2003-09-02 for test, don't use cache ????? -#if 0 - /*search cache no matter MMU enabled/disabled */ - cache = mmu_cache_search (state, I_CACHE (), va); - if (cache) { - *instr = cache->data[va_cache_index (va, I_CACHE ())]; - return 0; - } -#endif - /*if MMU disabled or C flag is set alloc cache */ - if (MMU_Disabled) { - c = 1; - pa = va; - } - else { - c = tlb_c_flag (tlb); - pa = tlb_va_to_pa (tlb, va); - } - - //chy 2003-09-03 only read mem, don't use cache now,will change later ???? - //*instr = mem_read_word (state, pa); - bus_read(32, pa, instr); -#if 0 -//----------------------------------------------------------- - //chy 2003-09-02 for test???? - if (pa >= 0xa01c8000 && pa <= 0xa01c8020) { - printf ("SKYEYE:load_instr: pa %x, va %x,instr %x, R15 %x\n", - pa, va, *instr, state->Reg[15]); - } - -//---------------------------------------------------------------------- -#endif - return NO_FAULT; - - if (c) { - int index; - - debug_count++; - cache = mmu_cache_alloc (state, I_CACHE (), va, pa); - index = va_cache_index (va, I_CACHE ()); - *instr = cache->data[va_cache_index (va, I_CACHE ())]; - } - else - //*instr = mem_read_word (state, pa); - bus_read(32, pa, instr); - - return NO_FAULT; -}; - - - -static fault_t - xscale_mmu_read_byte (ARMul_State * state, ARMword virt_addr, - ARMword * data) -{ - //ARMword temp,offset; - fault_t fault; - fault = xscale_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE); - return fault; -} - -static fault_t - xscale_mmu_read_halfword (ARMul_State * state, ARMword virt_addr, - ARMword * data) -{ - //ARMword temp,offset; - fault_t fault; - fault = xscale_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE); - return fault; -} - -static fault_t - xscale_mmu_read_word (ARMul_State * state, ARMword virt_addr, - ARMword * data) -{ - return xscale_mmu_read (state, virt_addr, data, ARM_WORD_TYPE); -} - - - - -static fault_t - xscale_mmu_read (ARMul_State * state, ARMword va, ARMword * data, - ARMword datatype) -{ - fault_t fault; -// rb_entry_t *rb; - tlb_entry_t *tlb; - cache_line_t *cache; - ARMword pa, real_va, temp, offset; - //chy 2003-09-02 for test ???? - static unsigned chyst1 = 0, chyst2 = 0; - - DEBUG_LOG(ARM11, "va = %x\n", va); - - va = mmu_pid_va_map (va); - real_va = va; - /*if MMU disabled, memory_read */ - if (MMU_Disabled) { - //*data = mem_read_word(state, va); - if (datatype == ARM_BYTE_TYPE) - //*data = mem_read_byte (state, va); - bus_read(8, va, data); - else if (datatype == ARM_HALFWORD_TYPE) - //*data = mem_read_halfword (state, va); - bus_read(16, va, data); - else if (datatype == ARM_WORD_TYPE) - //*data = mem_read_word (state, va); - bus_read(32, va, data); - else { - printf ("SKYEYE:1 xscale_mmu_read error: unknown data type %d\n", datatype); - // skyeye_exit (-1); - } - - return NO_FAULT; - } - - /*align check */ - if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) || - ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } // else - - va &= ~(WORD_SIZE - 1); - - /*translate va to tlb */ - fault = translate (state, va, D_TLB (), &tlb); - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - return fault; - } - /*check access permission */ - fault = check_access (state, va, tlb, 1); - if (fault) - return fault; - -#if 0 -//------------------------------------------------ -//chy 2003-09-02 for test only ,should commit ???? - if (datatype == ARM_WORD_TYPE) { - if (real_va >= 0xffff0000 && real_va <= 0xffff0020) { - pa = tlb_va_to_pa (tlb, va); - *data = mem_read_word (state, pa); - chyst1++; - printf ("**SKYEYE:mmu_read word %d: pa %x, va %x, data %x, R15 %x\n", chyst1, pa, real_va, *data, state->Reg[15]); - /* - cache==mmu_cache_search(state,MAIN_D_CACHE(),va); - if(cache){ - *data = cache->data[va_cache_index(va, MAIN_D_CACHE())]; - printf("cached data %x\n",*data); - }else printf("no cached data\n"); - */ - } - } -//------------------------------------------------- -#endif -#if 0 - /*search in read buffer */ - rb = mmu_rb_search (RB (), va); - if (rb) { - if (rb->fault) - return rb->fault; - *data = rb->data[(va & (rb_masks[rb->type] - 1)) >> WORD_SHT]; - goto datatrans; - //return 0; - }; -#endif - - /*2004-07-19 chy: add support of xscale MMU CacheDisabled option */ - if (MMU_CacheDisabled) { - //if(1){ can be used to test cache error - /*get phy_addr */ - pa = tlb_va_to_pa (tlb, real_va); - if (datatype == ARM_BYTE_TYPE) - //*data = mem_read_byte (state, pa); - bus_read(8, pa, data); - else if (datatype == ARM_HALFWORD_TYPE) - //*data = mem_read_halfword (state, pa); - bus_read(16, pa, data); - else if (datatype == ARM_WORD_TYPE) - //*data = mem_read_word (state, pa); - bus_read(32, pa, data); - else { - printf ("SKYEYE:MMU_CacheDisabled xscale_mmu_read error: unknown data type %d\n", datatype); - // skyeye_exit (-1); - } - return NO_FAULT; - } - - - /*search main cache */ - cache = mmu_cache_search (state, MAIN_D_CACHE (), va); - if (cache) { - *data = cache->data[va_cache_index (va, MAIN_D_CACHE ())]; -#if 0 -//------------------------------------------------------------------------ -//chy 2003-09-02 for test only ,should commit ???? - if (real_va >= 0xffff0000 && real_va <= 0xffff0020) { - pa = tlb_va_to_pa (tlb, va); - chyst2++; - printf ("**SKYEYE:mmu_read wordk:cache %d: pa %x, va %x, data %x, R15 %x\n", chyst2, pa, real_va, *data, state->Reg[15]); - } -//------------------------------------------------------------------- -#endif - goto datatrans; - //return 0; - } - //chy 2003-08-24, now maybe we don't need minidcache ???? -#if 0 - /*search mini cache */ - cache = mmu_cache_search (state, MINI_D_CACHE (), va); - if (cache) { - *data = cache->data[va_cache_index (va, MINI_D_CACHE ())]; - goto datatrans; - //return 0; - } -#endif - /*get phy_addr */ - pa = tlb_va_to_pa (tlb, va); - //chy 2003-08-24 , in xscale it means what ????? -#if 0 - if ((pa >= 0xe0000000) && (pa < 0xe8000000)) { - - if (tlb_c_flag (tlb)) { - if (tlb_b_flag (tlb)) { - mmu_cache_soft_flush (state, MAIN_D_CACHE (), - pa); - } - else { - mmu_cache_soft_flush (state, MINI_D_CACHE (), - pa); - } - } - return 0; - } -#endif - //chy 2003-08-24, check phy addr - //ywc 2004-11-30, inactive this check because of using 0xc0000000 as the framebuffer start address - /* - if(pa >= 0xb0000000){ - printf("SKYEYE:xscale_mmu_read: phy address 0x%x error,reg[15] 0x%x\n",pa,state->Reg[15]); - return 0; - } - */ - - //chy 2003-08-24, now maybe we don't need wb ???? -#if 0 - /*if Buffer, drain Write Buffer first */ - if (tlb_b_flag (tlb)) - mmu_wb_drain_all (state, WB ()); -#endif - /*alloc cache or mem_read */ - if (tlb_c_flag (tlb) && MMU_DCacheEnabled) { - cache_s *cache_t; - - if (tlb_b_flag (tlb)) - cache_t = MAIN_D_CACHE (); - else - cache_t = MINI_D_CACHE (); - cache = mmu_cache_alloc (state, cache_t, va, pa); - *data = cache->data[va_cache_index (va, cache_t)]; - } - else { - //*data = mem_read_word(state, pa); - if (datatype == ARM_BYTE_TYPE) - //*data = mem_read_byte (state, pa | (real_va & 3)); - bus_read(8, pa | (real_va & 3), data); - else if (datatype == ARM_HALFWORD_TYPE) - //*data = mem_read_halfword (state, pa | (real_va & 2)); - bus_read(16, pa | (real_va & 2), data); - else if (datatype == ARM_WORD_TYPE) - //*data = mem_read_word (state, pa); - bus_read(32, pa, data); - else { - printf ("SKYEYE:2 xscale_mmu_read error: unknown data type %d\n", datatype); - // skyeye_exit (-1); - } - return NO_FAULT; - } - - - datatrans: - if (datatype == ARM_HALFWORD_TYPE) { - temp = *data; - offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */ - *data = (temp >> offset) & 0xffff; - } - else if (datatype == ARM_BYTE_TYPE) { - temp = *data; - offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */ - *data = (temp >> offset & 0xffL); - } - end: - return NO_FAULT; -} - - -static fault_t - xscale_mmu_write_byte (ARMul_State * state, ARMword virt_addr, - ARMword data) -{ - return xscale_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE); -} - -static fault_t - xscale_mmu_write_halfword (ARMul_State * state, ARMword virt_addr, - ARMword data) -{ - return xscale_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE); -} - -static fault_t - xscale_mmu_write_word (ARMul_State * state, ARMword virt_addr, - ARMword data) -{ - return xscale_mmu_write (state, virt_addr, data, ARM_WORD_TYPE); -} - - - -static fault_t - xscale_mmu_write (ARMul_State * state, ARMword va, ARMword data, - ARMword datatype) -{ - tlb_entry_t *tlb; - cache_line_t *cache; - cache_s *cache_t; - int b; - ARMword pa, real_va, temp, offset; - fault_t fault; - - ARMword index; -//chy 2003-09-02 for test ???? -// static unsigned chyst1=0,chyst2=0; - - DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data); - va = mmu_pid_va_map (va); - real_va = va; - - if (MMU_Disabled) { - //mem_write_word(state, va, data); - if (datatype == ARM_BYTE_TYPE) - //mem_write_byte (state, va, data); - bus_write(8, va, data); - else if (datatype == ARM_HALFWORD_TYPE) - //mem_write_halfword (state, va, data); - bus_write(16, va, data); - else if (datatype == ARM_WORD_TYPE) - //mem_write_word (state, va, data); - bus_write(32, va, data); - else { - printf ("SKYEYE:1 xscale_mmu_write error: unknown data type %d\n", datatype); - // skyeye_exit (-1); - } - - return NO_FAULT; - } - /*align check */ - if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) || - ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } //else - va &= ~(WORD_SIZE - 1); - /*tlb translate */ - fault = translate (state, va, D_TLB (), &tlb); - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - return fault; - } - /*tlb check access */ - fault = check_access (state, va, tlb, 0); - if (fault) { - DEBUG_LOG(ARM11, "check_access\n"); - return fault; - } - - /*2004-07-19 chy: add support for xscale MMU_CacheDisabled */ - if (MMU_CacheDisabled) { - //if(1){ can be used to test the cache error - /*get phy_addr */ - pa = tlb_va_to_pa (tlb, real_va); - if (datatype == ARM_BYTE_TYPE) - //mem_write_byte (state, pa, data); - bus_write(8, pa, data); - else if (datatype == ARM_HALFWORD_TYPE) - //mem_write_halfword (state, pa, data); - bus_write(16, pa, data); - else if (datatype == ARM_WORD_TYPE) - //mem_write_word (state, pa, data); - bus_write(32, pa , data); - else { - printf ("SKYEYE:MMU_CacheDisabled xscale_mmu_write error: unknown data type %d\n", datatype); - // skyeye_exit (-1); - } - - return NO_FAULT; - } - - /*search main cache */ - b = tlb_b_flag (tlb); - pa = tlb_va_to_pa (tlb, va); - cache = mmu_cache_search (state, MAIN_D_CACHE (), va); - if (cache) { - cache_t = MAIN_D_CACHE (); - goto has_cache; - } - //chy 2003-08-24, now maybe we don't need minidcache ???? -#if 0 - /*search mini cache */ - cache = mmu_cache_search (state, MINI_D_CACHE (), va); - if (cache) { - cache_t = MINI_D_CACHE (); - goto has_cache; - } -#endif - b = tlb_b_flag (tlb); - pa = tlb_va_to_pa (tlb, va); - //chy 2003-08-24, check phy addr 0xa0000000, size 0x04000000 - //ywc 2004-11-30, inactive this check because of using 0xc0000000 as the framebuffer start address - /* - if(pa >= 0xb0000000){ - printf("SKYEYE:xscale_mmu_write phy address 0x%x error,reg[15] 0x%x\n",pa,state->Reg[15]); - return 0; - } - */ - - //chy 2003-08-24, now maybe we don't need WB ???? -#if 0 - if (b) { - if (MMU_WBEnabled) { - if (datatype == ARM_WORD_TYPE) - mmu_wb_write_bytes (state, WB (), pa, &data, - 4); - else if (datatype == ARM_HALFWORD_TYPE) - mmu_wb_write_bytes (state, WB (), - (pa | (real_va & 2)), - &data, 2); - else if (datatype == ARM_BYTE_TYPE) - mmu_wb_write_bytes (state, WB (), - (pa | (real_va & 3)), - &data, 1); - - } - else { - if (datatype == ARM_WORD_TYPE) - mem_write_word (state, pa, data); - else if (datatype == ARM_HALFWORD_TYPE) - mem_write_halfword (state, - (pa | (real_va & 2)), - data); - else if (datatype == ARM_BYTE_TYPE) - mem_write_byte (state, (pa | (real_va & 3)), - data); - } - } - else { - - mmu_wb_drain_all (state, WB ()); - - if (datatype == ARM_WORD_TYPE) - mem_write_word (state, pa, data); - else if (datatype == ARM_HALFWORD_TYPE) - mem_write_halfword (state, (pa | (real_va & 2)), - data); - else if (datatype == ARM_BYTE_TYPE) - mem_write_byte (state, (pa | (real_va & 3)), data); - } -#endif - //chy 2003-08-24, just write phy addr - if (datatype == ARM_WORD_TYPE) - //mem_write_word (state, pa, data); - bus_write(32, pa, data); - else if (datatype == ARM_HALFWORD_TYPE) - //mem_write_halfword (state, (pa | (real_va & 2)), data); - bus_write(16, pa | (real_va & 2), data); - else if (datatype == ARM_BYTE_TYPE) - //mem_write_byte (state, (pa | (real_va & 3)), data); - bus_write(8, (pa | (real_va & 3)), data); -#if 0 -//------------------------------------------------------------- -//chy 2003-09-02 for test ???? - if (datatype == ARM_WORD_TYPE) { - if (real_va >= 0xffff0000 && real_va <= 0xffff0020) { - printf ("**SKYEYE:mmu_write word: pa %x, va %x, data %x, R15 %x \n", pa, real_va, data, state->Reg[15]); - } - } -//-------------------------------------------------------------- -#endif - return NO_FAULT; - - has_cache: - index = va_cache_index (va, cache_t); - //cache->data[index] = data; - - if (datatype == ARM_WORD_TYPE) - cache->data[index] = data; - else if (datatype == ARM_HALFWORD_TYPE) { - temp = cache->data[index]; - offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */ - cache->data[index] = - (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << - offset); - } - else if (datatype == ARM_BYTE_TYPE) { - temp = cache->data[index]; - offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */ - cache->data[index] = - (temp & ~(0xffL << offset)) | ((data & 0xffL) << - offset); - } - - if (index < (cache_t->width >> (WORD_SHT + 1))) - cache->tag |= TAG_FIRST_HALF_DIRTY; - else - cache->tag |= TAG_LAST_HALF_DIRTY; -//------------------------------------------------------------- -//chy 2003-09-03 be sure the changed value will be in memory as soon as possible, so I cache can get the newest value -#if 0 - { - if (datatype == ARM_WORD_TYPE) - mem_write_word (state, pa, data); - else if (datatype == ARM_HALFWORD_TYPE) - mem_write_halfword (state, (pa | (real_va & 2)), - data); - else if (datatype == ARM_BYTE_TYPE) - mem_write_byte (state, (pa | (real_va & 3)), data); - } -#endif -#if 0 -//chy 2003-09-02 for test ???? - if (datatype == ARM_WORD_TYPE) { - if (real_va >= 0xffff0000 && real_va <= 0xffff0020) { - printf ("**SKYEYE:mmu_write word:cache: pa %x, va %x, data %x, R15 %x\n", pa, real_va, data, state->Reg[15]); - } - } -//------------------------------------------------------------- -#endif - if (datatype == ARM_WORD_TYPE) - //mem_write_word (state, pa, data); - bus_write(32, pa, data); - else if (datatype == ARM_HALFWORD_TYPE) - //mem_write_halfword (state, (pa | (real_va & 2)), data); - bus_write(16, pa | (real_va & 2), data); - else if (datatype == ARM_BYTE_TYPE) - //mem_write_byte (state, (pa | (real_va & 3)), data); - bus_write(8, (pa | (real_va & 3)), data); - return NO_FAULT; -} - -ARMword xscale_cp15_mrc (ARMul_State * state, - unsigned type, ARMword instr, ARMword * value) -{ - return xscale_mmu_mrc (state, instr, value); -} - -ARMword xscale_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value) -{ - ARMword data; - unsigned opcode_2 = BITS (5, 7); - unsigned CRm = BITS (0, 3); - unsigned reg = BITS (16, 19); - unsigned result; - mmu_regnum_t creg = (mmu_regnum_t)reg; - -/* - printf("SKYEYE: xscale_cp15_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\ - state->Reg[15], instr); -*/ - switch (creg) { - case MMU_ID: //XSCALE_CP15 - //printf("mmu_mrc read ID \n"); - data = (opcode_2 ? state->mmu.cache_type : state->cpu-> - cpu_val); - break; - case MMU_CONTROL: //XSCALE_CP15_AUX_CONTROL - //printf("mmu_mrc read CONTROL \n"); - data = (opcode_2 ? state->mmu.aux_control : state->mmu. - control); - break; - case MMU_TRANSLATION_TABLE_BASE: - //printf("mmu_mrc read TTB \n"); - data = state->mmu.translation_table_base; - break; - case MMU_DOMAIN_ACCESS_CONTROL: - //printf("mmu_mrc read DACR \n"); - data = state->mmu.domain_access_control; - break; - case MMU_FAULT_STATUS: - //printf("mmu_mrc read FSR \n"); - data = state->mmu.fault_status; - break; - case MMU_FAULT_ADDRESS: - //printf("mmu_mrc read FAR \n"); - data = state->mmu.fault_address; - break; - case MMU_PID: - //printf("mmu_mrc read PID \n"); - data = state->mmu.process_id; - case XSCALE_CP15_COPRO_ACCESS: - //printf("xscale cp15 read coprocessor access\n"); - data = state->mmu.copro_access; - break; - default: - data = 0; - printf ("SKYEYE: xscale_cp15_mrc read UNKNOWN - reg %d, pc 0x%x\n", creg, state->Reg[15]); - // skyeye_exit (-1); - break; - } - *value = data; - //printf("SKYEYE: xscale_cp15_mrc:end value 0x%x\n",data); - return ARMul_DONE; -} - -void xscale_cp15_cache_ops (ARMul_State * state, ARMword instr, ARMword value) -{ -//chy: 2003-08-24 now, the BTB isn't simualted ....???? - - unsigned CRm, OPC_2; - - CRm = BITS (0, 3); - OPC_2 = BITS (5, 7); - //err_msg("SKYEYE: xscale cp15_cache_ops:OPC_2 = 0x%x CRm = 0x%x, Reg15 0x%x\n", OPC_2, CRm,state->Reg[15]); - - if (OPC_2 == 0 && CRm == 7) { - mmu_cache_invalidate_all (state, I_CACHE ()); - mmu_cache_invalidate_all (state, MAIN_D_CACHE ()); - return; - } - - if (OPC_2 == 0 && CRm == 5) { - mmu_cache_invalidate_all (state, I_CACHE ()); - return; - } - if (OPC_2 == 1 && CRm == 5) { - mmu_cache_invalidate (state, I_CACHE (), value); - return; - } - - if (OPC_2 == 0 && CRm == 6) { - mmu_cache_invalidate_all (state, MAIN_D_CACHE ()); - return; - } - - if (OPC_2 == 1 && CRm == 6) { - mmu_cache_invalidate (state, MAIN_D_CACHE (), value); - return; - } - - if (OPC_2 == 1 && CRm == 0xa) { - mmu_cache_clean (state, MAIN_D_CACHE (), value); - return; - } - - if (OPC_2 == 4 && CRm == 0xa) { - mmu_wb_drain_all (state, WB ()); - return; - } - - if (OPC_2 == 6 && CRm == 5) { - //chy 2004-07-19 shoud fix in the future????!!!! - //printf("SKYEYE: xscale_cp15_cache_ops:invalidate BTB CANT!!!!!!!!!!\n"); - //exit(-1); - return; - } - - if (OPC_2 == 5 && CRm == 2) { - //printf("SKYEYE: cp15_c_o: A L in D C, value %x, reg15 %x\n",value, state->Reg[15]); - //exit(-1); - //chy 2003-09-01 for test - mmu_cache_invalidate_all (state, MAIN_D_CACHE ()); - return; - } - - ERROR_LOG(ARM11, "SKYEYE: xscale cp15_cache_ops:Unknown OPC_2 = 0x%x CRm = 0x%x, Reg15 0x%x\n", OPC_2, CRm, state->Reg[15]); - // skyeye_exit (-1); -} - -static void - xscale_cp15_tlb_ops (ARMul_State * state, ARMword instr, - ARMword value) -{ - int CRm, OPC_2; - - CRm = BITS (0, 3); - OPC_2 = BITS (5, 7); - - - //err_msg("SKYEYE:xscale_cp15_tlb_ops:OPC_2 = 0x%x CRm = 0x%x,Reg[15] 0x%x\n", OPC_2, CRm,state->Reg[15]); - if (OPC_2 == 0 && CRm == 0x7) { - mmu_tlb_invalidate_all (state, I_TLB ()); - mmu_tlb_invalidate_all (state, D_TLB ()); - return; - } - - if (OPC_2 == 0 && CRm == 0x5) { - mmu_tlb_invalidate_all (state, I_TLB ()); - return; - } - - if (OPC_2 == 1 && CRm == 0x5) { - mmu_tlb_invalidate_entry (state, I_TLB (), value); - return; - } - - if (OPC_2 == 0 && CRm == 0x6) { - mmu_tlb_invalidate_all (state, D_TLB ()); - return; - } - - if (OPC_2 == 1 && CRm == 0x6) { - mmu_tlb_invalidate_entry (state, D_TLB (), value); - return; - } - - ERROR_LOG(ARM11, "SKYEYE:xscale_cp15_tlb_ops:Unknow OPC_2 = 0x%x CRm = 0x%x,Reg[15] 0x%x\n", OPC_2, CRm, state->Reg[15]); - // skyeye_exit (-1); -} - - -ARMword xscale_cp15_mcr (ARMul_State * state, - unsigned type, ARMword instr, ARMword value) -{ - return xscale_mmu_mcr (state, instr, value); -} - -ARMword xscale_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value) -{ - ARMword data; - unsigned opcode_2 = BITS (5, 7); - unsigned CRm = BITS (0, 3); - unsigned reg = BITS (16, 19); - unsigned result; - mmu_regnum_t creg = (mmu_regnum_t)reg; - - //printf("SKYEYE: xscale_cp15_mcr: opcode_2 0x%x, CRm 0x%x, reg ox%x, value 0x%x, reg[15] 0x%x, instr 0x%x\n",opcode_2,CRm,reg, value, state->Reg[15], instr); - - switch (creg) { - case MMU_CONTROL: - //printf("mmu_mcr wrote CONTROL val 0x%x \n",value); - state->mmu.control = - (opcode_2 ? (value & 0x33) : (value & 0x3FFF)); - break; - case MMU_TRANSLATION_TABLE_BASE: - //printf("mmu_mcr wrote TTB val 0x%x \n",value); - state->mmu.translation_table_base = value & 0xFFFFC000; - break; - case MMU_DOMAIN_ACCESS_CONTROL: - //printf("mmu_mcr wrote DACR val 0x%x \n",value); - state->mmu.domain_access_control = value; - break; - - case MMU_FAULT_STATUS: - //printf("mmu_mcr wrote FS val 0x%x \n",value); - state->mmu.fault_status = value & 0x6FF; - break; - case MMU_FAULT_ADDRESS: - //printf("mmu_mcr wrote FA val 0x%x \n",value); - state->mmu.fault_address = value; - break; - - case MMU_CACHE_OPS: -// printf("mmu_mcr wrote CO val 0x%x \n",value); - xscale_cp15_cache_ops (state, instr, value); - break; - case MMU_TLB_OPS: - //printf("mmu_mcr wrote TO val 0x%x \n",value); - xscale_cp15_tlb_ops (state, instr, value); - break; - case MMU_PID: - //printf("mmu_mcr wrote PID val 0x%x \n",value); - state->mmu.process_id = value & 0xfe000000; - break; - case XSCALE_CP15_COPRO_ACCESS: - //printf("xscale cp15 write coprocessor access val 0x %x\n",value); - state->mmu.copro_access = value & 0x3ff; - break; - - default: - printf ("SKYEYE: xscale_cp15_mcr wrote UNKNOWN - reg %d, reg15 0x%x\n", creg, state->Reg[15]); - break; - } - //printf("SKYEYE: xscale_cp15_mcr wrote val 0x%x\n", value); - return 0; -} - -//teawater add for arm2x86 2005.06.24------------------------------------------- -static int xscale_mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, - ARMword * phys_addr) -{ - fault_t fault; - tlb_entry_t *tlb; - - virt_addr = mmu_pid_va_map (virt_addr); - if (MMU_Enabled) { - - /*align check */ - if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) { - DEBUG_LOG(ARM11, "align\n"); - return ALIGNMENT_FAULT; - } - else - virt_addr &= ~(WORD_SIZE - 1); - - /*translate tlb */ - fault = translate (state, virt_addr, I_TLB (), &tlb); - if (fault) { - DEBUG_LOG(ARM11, "translate\n"); - return fault; - } - - /*check access */ - fault = check_access (state, virt_addr, tlb, 1); - if (fault) { - DEBUG_LOG(ARM11, "check_fault\n"); - return fault; - } - } - - if (MMU_Disabled) { - *phys_addr = virt_addr; - } - else { - *phys_addr = tlb_va_to_pa (tlb, virt_addr); - } - - return (0); -} - -//AJ2D-------------------------------------------------------------------------- - -/*xscale mmu_ops_t*/ -//mmu_ops_t xscale_mmu_ops = { -// xscale_cp15_init, -// xscale_cp15_exit, -// xscale_mmu_read_byte, -// xscale_mmu_write_byte, -// xscale_mmu_read_halfword, -// xscale_mmu_write_halfword, -// xscale_mmu_read_word, -// xscale_mmu_write_word, -// xscale_mmu_load_instr, xscale_mmu_mcr, xscale_mmu_mrc, -////teawater add for arm2x86 2005.06.24------------------------------------------- -// xscale_mmu_v2p_dbct, -////AJ2D-------------------------------------------------------------------------- -//}; diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index fd574a7a1..8e71948c6 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h @@ -367,7 +367,6 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) int verbose; /* non-zero means print various messages like the banner */ - mmu_state_t mmu; int mmu_inited; //mem_state_t mem; /*remove io_state to skyeye_mach_*.c files */ diff --git a/src/core/arm/skyeye_common/armmmu.h b/src/core/arm/skyeye_common/armmmu.h index 818108c9c..30858f9ba 100644 --- a/src/core/arm/skyeye_common/armmmu.h +++ b/src/core/arm/skyeye_common/armmmu.h @@ -134,121 +134,4 @@ typedef enum fault_t } fault_t; -typedef struct mmu_ops_s -{ - /*initilization */ - int (*init) (ARMul_State * state); - /*free on exit */ - void (*exit) (ARMul_State * state); - /*read byte data */ - fault_t (*read_byte) (ARMul_State * state, ARMword va, - ARMword * data); - /*write byte data */ - fault_t (*write_byte) (ARMul_State * state, ARMword va, - ARMword data); - /*read halfword data */ - fault_t (*read_halfword) (ARMul_State * state, ARMword va, - ARMword * data); - /*write halfword data */ - fault_t (*write_halfword) (ARMul_State * state, ARMword va, - ARMword data); - /*read word data */ - fault_t (*read_word) (ARMul_State * state, ARMword va, - ARMword * data); - /*write word data */ - fault_t (*write_word) (ARMul_State * state, ARMword va, - ARMword data); - /*load instr */ - fault_t (*load_instr) (ARMul_State * state, ARMword va, - ARMword * instr); - /*mcr */ - ARMword (*mcr) (ARMul_State * state, ARMword instr, ARMword val); - /*mrc */ - ARMword (*mrc) (ARMul_State * state, ARMword instr, ARMword * val); - - /*ywc 2005-04-16 convert virtual address to physics address */ - int (*v2p_dbct) (ARMul_State * state, ARMword virt_addr, - ARMword * phys_addr); -} mmu_ops_t; - - -#include "core/arm/interpreter/mmu/tlb.h" -#include "core/arm/interpreter/mmu/rb.h" -#include "core/arm/interpreter/mmu/wb.h" -#include "core/arm/interpreter/mmu/cache.h" - -/*special process mmu.h*/ -#include "core/arm/interpreter/mmu/sa_mmu.h" -//#include "core/arm/interpreter/mmu/arm7100_mmu.h" -//#include "core/arm/interpreter/mmu/arm920t_mmu.h" -//#include "core/arm/interpreter/mmu/arm926ejs_mmu.h" -#include "core/arm/interpreter/mmu/arm1176jzf_s_mmu.h" -//#include "core/arm/interpreter/mmu/cortex_a9_mmu.h" - -typedef struct mmu_state_t -{ - ARMword control; - ARMword translation_table_base; -/* dyf 201-08-11 for arm1176 */ - ARMword auxiliary_control; - ARMword coprocessor_access_control; - ARMword translation_table_base0; - ARMword translation_table_base1; - ARMword translation_table_ctrl; -/* arm1176 end */ - - ARMword domain_access_control; - ARMword fault_status; - ARMword fault_statusi; /* prefetch fault status */ - ARMword fault_address; - ARMword last_domain; - ARMword process_id; - ARMword context_id; - ARMword thread_uro_id; - ARMword cache_locked_down; - ARMword tlb_locked_down; -//chy 2003-08-24 for xscale - ARMword cache_type; // 0 - ARMword aux_control; // 1 - ARMword copro_access; // 15 - - mmu_ops_t ops; - union - { - sa_mmu_t sa_mmu; - //arm7100_mmu_t arm7100_mmu; - //arm920t_mmu_t arm920t_mmu; - //arm926ejs_mmu_t arm926ejs_mmu; - } u; -} mmu_state_t; - -int mmu_init (ARMul_State * state); -int mmu_reset (ARMul_State * state); -void mmu_exit (ARMul_State * state); - -fault_t mmu_read_word (ARMul_State * state, ARMword virt_addr, - ARMword * data); -fault_t mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data); -fault_t mmu_load_instr (ARMul_State * state, ARMword virt_addr, - ARMword * instr); - -ARMword mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value); -void mmu_mcr (ARMul_State * state, ARMword instr, ARMword value); - -/*ywc 20050416*/ -int mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, - ARMword * phys_addr); - -fault_t -mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data); -fault_t -mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data); -fault_t -mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data); -fault_t -mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data); -fault_t -mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data); -fault_t -mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data); #endif /* _ARMMMU_H_ */ |