summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbunnei <ericbunnie@gmail.com>2014-03-30 03:53:07 +0200
committerbunnei <ericbunnie@gmail.com>2014-03-30 03:53:07 +0200
commit6b255111d5c130e49846b1727302111f423cb157 (patch)
tree335ba0e8c06480b4f8f777651e83525ba647317f
parentadded a GetPointer function to Memory for use with ELF loading (diff)
downloadyuzu-6b255111d5c130e49846b1727302111f423cb157.tar
yuzu-6b255111d5c130e49846b1727302111f423cb157.tar.gz
yuzu-6b255111d5c130e49846b1727302111f423cb157.tar.bz2
yuzu-6b255111d5c130e49846b1727302111f423cb157.tar.lz
yuzu-6b255111d5c130e49846b1727302111f423cb157.tar.xz
yuzu-6b255111d5c130e49846b1727302111f423cb157.tar.zst
yuzu-6b255111d5c130e49846b1727302111f423cb157.zip
-rw-r--r--src/core/core.vcxproj8
-rw-r--r--src/core/core.vcxproj.filters20
-rw-r--r--src/core/src/arm/armemu.cpp21
-rw-r--r--src/core/src/arm/armemu.h15
-rw-r--r--src/core/src/arm/arminit.cpp163
-rw-r--r--src/core/src/arm/armmmu.cpp146
-rw-r--r--src/core/src/arm/armos.cpp742
-rw-r--r--src/core/src/arm/armsupp.cpp953
-rw-r--r--src/core/src/arm/armvirt.cpp680
9 files changed, 2582 insertions, 166 deletions
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index 9d6c28216..a774f9e4b 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -139,9 +139,14 @@
<ItemGroup>
<ClCompile Include="src\arm\armemu.cpp" />
<ClCompile Include="src\arm\arminit.cpp" />
+ <ClCompile Include="src\arm\armmmu.cpp" />
+ <ClCompile Include="src\arm\armos.cpp" />
+ <ClCompile Include="src\arm\armsupp.cpp" />
+ <ClCompile Include="src\arm\armvirt.cpp" />
<ClCompile Include="src\arm\disassembler\arm_disasm.cpp" />
<ClCompile Include="src\core.cpp" />
<ClCompile Include="src\core_timing.cpp" />
+ <ClCompile Include="src\elf\elf_reader.cpp" />
<ClCompile Include="src\file_sys\directory_file_system.cpp" />
<ClCompile Include="src\file_sys\meta_file_system.cpp" />
<ClCompile Include="src\loader.cpp" />
@@ -165,7 +170,8 @@
<ClInclude Include="src\arm\skyeye_defs.h" />
<ClInclude Include="src\core.h" />
<ClInclude Include="src\core_timing.h" />
- <ClInclude Include="src\elf\elf.h" />
+ <ClInclude Include="src\elf\elf_reader.h" />
+ <ClInclude Include="src\elf\elf_types.h" />
<ClInclude Include="src\file_sys\directory_file_system.h" />
<ClInclude Include="src\file_sys\file_sys.h" />
<ClInclude Include="src\file_sys\meta_file_system.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 4d1ec576c..50d0cbc71 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -22,6 +22,21 @@
</ClCompile>
<ClCompile Include="src\system.cpp" />
<ClCompile Include="src\core_timing.cpp" />
+ <ClCompile Include="src\elf\elf_reader.cpp">
+ <Filter>elf</Filter>
+ </ClCompile>
+ <ClCompile Include="src\arm\armsupp.cpp">
+ <Filter>arm</Filter>
+ </ClCompile>
+ <ClCompile Include="src\arm\armvirt.cpp">
+ <Filter>arm</Filter>
+ </ClCompile>
+ <ClCompile Include="src\arm\armmmu.cpp">
+ <Filter>arm</Filter>
+ </ClCompile>
+ <ClCompile Include="src\arm\armos.cpp">
+ <Filter>arm</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="arm">
@@ -94,7 +109,10 @@
</ClInclude>
<ClInclude Include="src\system.h" />
<ClInclude Include="src\core_timing.h" />
- <ClInclude Include="src\elf\elf.h">
+ <ClInclude Include="src\elf\elf_reader.h">
+ <Filter>elf</Filter>
+ </ClInclude>
+ <ClInclude Include="src\elf\elf_types.h">
<Filter>elf</Filter>
</ClInclude>
</ItemGroup>
diff --git a/src/core/src/arm/armemu.cpp b/src/core/src/arm/armemu.cpp
index e5c287236..362ae0fd1 100644
--- a/src/core/src/arm/armemu.cpp
+++ b/src/core/src/arm/armemu.cpp
@@ -21,6 +21,19 @@
#include "armemu.h"
#include "armos.h"
+void
+XScale_set_fsr_far(ARMul_State * state, ARMword fsr, ARMword _far)
+{
+ _dbg_assert_msg_(ARM11, false, "ImplementMe: XScale_set_fsr_far!");
+ //if (!state->is_XScale || (read_cp14_reg(10) & (1UL << 31)) == 0)
+ // return;
+ //
+ //write_cp15_reg(state, 5, 0, 0, fsr);
+ //write_cp15_reg(state, 6, 0, 0, _far);
+}
+
+#define ARMul_Debug(x,y,z) 0 // Disabling this /bunnei
+
//#include "skyeye_callback.h"
//#include "skyeye_bus.h"
//#include "sim_control.h"
@@ -2174,10 +2187,10 @@ ARMul_Emulate26 (ARMul_State * state)
(state,
ARMul_CP15_R5_MMU_EXCPT,
pc);
- if (!XScale_debug_moe
- (state,
- ARMul_CP14_R10_MOE_BT))
- break;
+ //if (!XScale_debug_moe
+ // (state,
+ // ARMul_CP14_R10_MOE_BT))
+ // break; // Disabled /bunnei
}
/* Force the next instruction to be refetched. */
diff --git a/src/core/src/arm/armemu.h b/src/core/src/arm/armemu.h
index ae5c35aee..d4afa8e22 100644
--- a/src/core/src/arm/armemu.h
+++ b/src/core/src/arm/armemu.h
@@ -73,6 +73,7 @@ extern ARMword isize;
#define ASSIGNT(res) state->TFlag = res
#define INSN_SIZE (TFLAG ? 2 : 4)
#else
+#define TBIT (1L << 5)
#define INSN_SIZE 4
#define TFLAG 0
#endif
@@ -229,12 +230,12 @@ extern ARMword isize;
} \
while (0)
-#ifndef MODE32
+//#ifndef MODE32
#define VECTORS 0x20
#define LEGALADDR 0x03ffffff
#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig)
#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig)
-#endif
+//#endif
#define INTERNALABORT(address) \
do \
@@ -409,10 +410,12 @@ extern ARMword isize;
|| (! (STATE)->is_XScale) \
|| (read_cp15_reg (15, 0, 1) & (1 << (CP))))
*/
-#define CP_ACCESS_ALLOWED(STATE, CP) \
- ( ((CP) >= 14) \
- || (! (STATE)->is_XScale) \
- || (xscale_cp15_cp_access_allowed(STATE,15,CP)))
+//#define CP_ACCESS_ALLOWED(STATE, CP) \
+// (((CP) >= 14) \
+// || (!(STATE)->is_XScale) \
+// || (xscale_cp15_cp_access_allowed(STATE, 15, CP)))
+
+#define CP_ACCESS_ALLOWED(STATE, CP) false // Disabled coprocessor shit /bunnei
/* Macro to rotate n right by b bits. */
#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b))))
diff --git a/src/core/src/arm/arminit.cpp b/src/core/src/arm/arminit.cpp
index 9327f8f6a..d394be66c 100644
--- a/src/core/src/arm/arminit.cpp
+++ b/src/core/src/arm/arminit.cpp
@@ -271,7 +271,7 @@ below line sould be in skyeye_mach_XXX.c 's XXX_mach_init function
/* Only initialse the coprocessor support once we
know what kind of chip we are dealing with. */
- ARMul_CoProInit (state);
+ //ARMul_CoProInit (state); Commented out /bunnei
}
@@ -318,7 +318,7 @@ ARMul_Reset (ARMul_State * state)
state->NumFcycles = 0;
//fprintf(stderr,"armul_reset 3: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
- mmu_reset (state);
+ //mmu_reset (state); Commented out /bunnei
//fprintf(stderr,"armul_reset 4: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
//mem_reset (state); /* move to memory/ram.c */
@@ -436,7 +436,8 @@ ARMul_DoProg (ARMul_State * state)
}
else {
- pc = ARMul_Emulate26 (state);
+ //pc = ARMul_Emulate26 (state); Commented out /bunnei
+ ERROR_LOG(ARM11, "Unsupported ARM 26-bit Mode!");
}
//chy 2006-02-22, should test debugmode first
//chy 2006-04-14, put below codes in ARMul_Emulate
@@ -489,8 +490,10 @@ ARMul_DoInstr (ARMul_State * state)
#endif
}
- else
- pc = ARMul_Emulate26 (state);
+ else {
+ //pc = ARMul_Emulate26 (state); Commented out /bunnei
+ ERROR_LOG(ARM11, "Unsupported ARM 26-bit Mode!");
+ }
return (pc);
}
@@ -501,78 +504,78 @@ ARMul_DoInstr (ARMul_State * state)
* appropriate vector's memory address (0,4,8 ....) *
\***************************************************************************/
-//void
-//ARMul_Abort (ARMul_State * state, ARMword vector)
-//{
-// ARMword temp;
-// int isize = INSN_SIZE;
-// int esize = (TFLAG ? 0 : 4);
-// int e2size = (TFLAG ? -4 : 0);
-//
-// state->Aborted = FALSE;
-//
-// if (state->prog32Sig)
-// if (ARMul_MODE26BIT)
-// temp = R15PC;
-// else
-// temp = state->Reg[15];
-// else
-// temp = R15PC | ECC | ER15INT | EMODE;
-//
-// switch (vector) {
-// case ARMul_ResetV: /* RESET */
-// SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE,
-// 0);
-// break;
-// case ARMul_UndefinedInstrV: /* Undefined Instruction */
-// SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE,
-// isize);
-// break;
-// case ARMul_SWIV: /* Software Interrupt */
-// SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
-// isize);
-// break;
-// case ARMul_PrefetchAbortV: /* Prefetch Abort */
-// state->AbortAddr = 1;
-// SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
-// esize);
-// break;
-// case ARMul_DataAbortV: /* Data Abort */
-// SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
-// e2size);
-// break;
-// case ARMul_AddrExceptnV: /* Address Exception */
-// SETABORT (IBIT, SVC26MODE, isize);
-// break;
-// case ARMul_IRQV: /* IRQ */
-// //chy 2003-09-02 the if sentence seems no use
-//#if 0
-// if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
-// || (temp & ARMul_CP13_R0_IRQ))
-//#endif
-// SETABORT (IBIT,
-// state->prog32Sig ? IRQ32MODE : IRQ26MODE,
-// esize);
-// break;
-// case ARMul_FIQV: /* FIQ */
-// //chy 2003-09-02 the if sentence seems no use
-//#if 0
-// if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
-// || (temp & ARMul_CP13_R0_FIQ))
-//#endif
-// SETABORT (INTBITS,
-// state->prog32Sig ? FIQ32MODE : FIQ26MODE,
-// esize);
-// break;
-// }
-//
-// if (ARMul_MODE32BIT) {
-// if (state->mmu.control & CONTROL_VECTOR)
-// vector += 0xffff0000; //for v4 high exception address
-// if (state->vector_remap_flag)
-// vector += state->vector_remap_addr; /* support some remap function in LPC processor */
-// ARMul_SetR15 (state, vector);
-// }
-// else
-// ARMul_SetR15 (state, R15CCINTMODE | vector);
-//}
+void
+ARMul_Abort (ARMul_State * state, ARMword vector)
+{
+ ARMword temp;
+ int isize = INSN_SIZE;
+ int esize = (TFLAG ? 0 : 4);
+ int e2size = (TFLAG ? -4 : 0);
+
+ state->Aborted = FALSE;
+
+ if (state->prog32Sig)
+ if (ARMul_MODE26BIT)
+ temp = R15PC;
+ else
+ temp = state->Reg[15];
+ else
+ temp = R15PC | ECC | ER15INT | EMODE;
+
+ switch (vector) {
+ case ARMul_ResetV: /* RESET */
+ SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE,
+ 0);
+ break;
+ case ARMul_UndefinedInstrV: /* Undefined Instruction */
+ SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE,
+ isize);
+ break;
+ case ARMul_SWIV: /* Software Interrupt */
+ SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
+ isize);
+ break;
+ case ARMul_PrefetchAbortV: /* Prefetch Abort */
+ state->AbortAddr = 1;
+ SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
+ esize);
+ break;
+ case ARMul_DataAbortV: /* Data Abort */
+ SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
+ e2size);
+ break;
+ case ARMul_AddrExceptnV: /* Address Exception */
+ SETABORT (IBIT, SVC26MODE, isize);
+ break;
+ case ARMul_IRQV: /* IRQ */
+ //chy 2003-09-02 the if sentence seems no use
+#if 0
+ if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
+ || (temp & ARMul_CP13_R0_IRQ))
+#endif
+ SETABORT (IBIT,
+ state->prog32Sig ? IRQ32MODE : IRQ26MODE,
+ esize);
+ break;
+ case ARMul_FIQV: /* FIQ */
+ //chy 2003-09-02 the if sentence seems no use
+#if 0
+ if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
+ || (temp & ARMul_CP13_R0_FIQ))
+#endif
+ SETABORT (INTBITS,
+ state->prog32Sig ? FIQ32MODE : FIQ26MODE,
+ esize);
+ break;
+ }
+
+ if (ARMul_MODE32BIT) {
+ if (state->mmu.control & CONTROL_VECTOR)
+ vector += 0xffff0000; //for v4 high exception address
+ if (state->vector_remap_flag)
+ vector += state->vector_remap_addr; /* support some remap function in LPC processor */
+ ARMul_SetR15 (state, vector);
+ }
+ else
+ ARMul_SetR15 (state, R15CCINTMODE | vector);
+}
diff --git a/src/core/src/arm/armmmu.cpp b/src/core/src/arm/armmmu.cpp
index 5ba81b52a..476f8051d 100644
--- a/src/core/src/arm/armmmu.cpp
+++ b/src/core/src/arm/armmmu.cpp
@@ -45,55 +45,51 @@ mmu_init (ARMul_State * state)
state->mmu.process_id = 0;
switch (state->cpu->cpu_val & state->cpu->cpu_mask) {
- case SA1100:
- case SA1110:
- SKYEYE_INFO("SKYEYE: use sa11xx mmu ops\n");
- state->mmu.ops = sa_mmu_ops;
- break;
- case PXA250:
- case PXA270: //xscale
- SKYEYE_INFO ("SKYEYE: use xscale mmu ops\n");
- state->mmu.ops = xscale_mmu_ops;
- break;
- case 0x41807200: //arm720t
- case 0x41007700: //arm7tdmi
- case 0x41007100: //arm7100
- SKYEYE_INFO ( "SKYEYE: use arm7100 mmu ops\n");
- state->mmu.ops = arm7100_mmu_ops;
- break;
- case 0x41009200:
- SKYEYE_INFO ("SKYEYE: use arm920t mmu ops\n");
- state->mmu.ops = arm920t_mmu_ops;
- break;
- case 0x41069260:
- SKYEYE_INFO ("SKYEYE: use arm926ejs mmu ops\n");
- state->mmu.ops = arm926ejs_mmu_ops;
- break;
+ //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:
- SKYEYE_INFO ("SKYEYE: use arm11jzf-s mmu ops\n");
- state->mmu.ops = arm1176jzf_s_mmu_ops;
+ NOTICE_LOG(ARM11, "SKYEYE: use arm11jzf-s mmu ops\n");
+ //state->mmu.ops = arm1176jzf_s_mmu_ops;
+ _dbg_assert_msg_(ARM11, false, "ImplementMe: arm1176jzf_s_mmu_ops!");
break;
- case 0xc090:
- SKYEYE_INFO ("SKYEYE: use cortex_a9 mmu ops\n");
- state->mmu.ops = cortex_a9_mmu_ops;
- break;
default:
- fprintf (stderr,
+ ERROR_LOG (ARM11,
"SKYEYE: armmmu.c : mmu_init: unknown cpu_val&cpu_mask 0x%x\n",
state->cpu->cpu_val & state->cpu->cpu_mask);
- skyeye_exit (-1);
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;
+ //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;
}
@@ -201,41 +197,43 @@ 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, generic_address_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:
- printf("In %s error size %d Line %d\n", __func__, size, __LINE__);
- break;
- }
- return No_exp;
-}
-/* dis_mmu_write for disassemble */
-exception_t arm_mmu_write(short size, generic_address_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;
-}
+//
+//
+///* 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/src/arm/armos.cpp b/src/core/src/arm/armos.cpp
new file mode 100644
index 000000000..43484ee5f
--- /dev/null
+++ b/src/core/src/arm/armos.cpp
@@ -0,0 +1,742 @@
+/* armos.c -- ARMulator OS interface: ARM6 Instruction Emulator.
+ Copyright (C) 1994 Advanced RISC Machines Ltd.
+
+ 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. */
+
+/* This file contains a model of Demon, ARM Ltd's Debug Monitor,
+including all the SWI's required to support the C library. The code in
+it is not really for the faint-hearted (especially the abort handling
+code), but it is a complete example. Defining NOOS will disable all the
+fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI
+0x11 to halt the emulator. */
+
+//chy 2005-09-12 disable below line
+//#include "config.h"
+
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include "skyeye_defs.h"
+#ifndef __USE_LARGEFILE64
+#define __USE_LARGEFILE64 /* When use 64 bit large file need define it! for stat64*/
+#endif
+#include <fcntl.h>
+#include <sys/stat.h>
+
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY 1
+#endif
+#ifndef O_RDWR
+#define O_RDWR 2
+#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#ifdef __STDC__
+#define unlink(s) remove(s)
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* For SEEK_SET etc */
+#endif
+
+#ifdef __riscos
+extern int _fisatty (FILE *);
+#define isatty_(f) _fisatty(f)
+#else
+#ifdef __ZTC__
+#include <io.h>
+#define isatty_(f) isatty((f)->_file)
+#else
+#ifdef macintosh
+#include <ioctl.h>
+#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
+#else
+#define isatty_(f) isatty (fileno (f))
+#endif
+#endif
+#endif
+
+#include "armdefs.h"
+#include "armos.h"
+#include "armemu.h"
+
+#ifndef NOOS
+#ifndef VALIDATE
+/* #ifndef ASIM */
+//chy 2005-09-12 disable below line
+//#include "armfpe.h"
+/* #endif */
+#endif
+#endif
+
+#define DUMP_SYSCALL 0
+#define dump(...) do { if (DUMP_SYSCALL) printf(__VA_ARGS__); } while(0)
+//#define debug(...) printf(__VA_ARGS__);
+#define debug(...) ;
+
+extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
+
+#ifndef FOPEN_MAX
+#define FOPEN_MAX 64
+#endif
+
+/***************************************************************************\
+* OS private Information *
+\***************************************************************************/
+
+unsigned arm_dyncom_SWI(ARMul_State * state, ARMword number)
+{
+ return ARMul_OSHandleSWI(state, number);
+}
+
+//mmap_area_t *mmap_global = NULL;
+
+static int translate_open_mode[] = {
+ O_RDONLY, /* "r" */
+ O_RDONLY + O_BINARY, /* "rb" */
+ O_RDWR, /* "r+" */
+ O_RDWR + O_BINARY, /* "r+b" */
+ O_WRONLY + O_CREAT + O_TRUNC, /* "w" */
+ O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */
+ O_RDWR + O_CREAT + O_TRUNC, /* "w+" */
+ O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */
+ O_WRONLY + O_APPEND + O_CREAT, /* "a" */
+ O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */
+ O_RDWR + O_APPEND + O_CREAT, /* "a+" */
+ O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */
+};
+//
+//static void
+//SWIWrite0 (ARMul_State * state, ARMword addr)
+//{
+// ARMword temp;
+//
+// //while ((temp = ARMul_ReadByte (state, addr++)) != 0)
+// while(1){
+// mem_read(8, addr++, &temp);
+// if(temp != 0)
+// (void) fputc ((char) temp, stdout);
+// else
+// break;
+// }
+//}
+//
+//static void
+//WriteCommandLineTo (ARMul_State * state, ARMword addr)
+//{
+// ARMword temp;
+// char *cptr = state->CommandLine;
+// if (cptr == NULL)
+// cptr = "\0";
+// do {
+// temp = (ARMword) * cptr++;
+// //ARMul_WriteByte (state, addr++, temp);
+// mem_write(8, addr++, temp);
+// }
+// while (temp != 0);
+//}
+//
+//static void
+//SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
+//{
+// char dummy[2000];
+// int flags;
+// int i;
+//
+// for (i = 0; (dummy[i] = ARMul_ReadByte (state, name + i)); i++);
+// assert(SWIflags< (sizeof(translate_open_mode)/ sizeof(translate_open_mode[0])));
+// /* Now we need to decode the Demon open mode */
+// flags = translate_open_mode[SWIflags];
+// flags = SWIflags;
+//
+// /* Filename ":tt" is special: it denotes stdin/out */
+// if (strcmp (dummy, ":tt") == 0) {
+// if (flags == O_RDONLY) /* opening tty "r" */
+// state->Reg[0] = 0; /* stdin */
+// else
+// state->Reg[0] = 1; /* stdout */
+// }
+// else {
+// state->Reg[0] = (int) open (dummy, flags, 0666);
+// }
+//}
+//
+//static void
+//SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
+//{
+// int res;
+// int i;
+// char *local = (char*) malloc (len);
+//
+// if (local == NULL) {
+// fprintf (stderr,
+// "sim: Unable to read 0x%ulx bytes - out of memory\n",
+// len);
+// return;
+// }
+//
+// res = read (f, local, len);
+// if (res > 0)
+// for (i = 0; i < res; i++)
+// //ARMul_WriteByte (state, ptr + i, local[i]);
+// mem_write(8, ptr + i, local[i]);
+// free (local);
+// //state->Reg[0] = res == -1 ? -1 : len - res;
+// state->Reg[0] = res;
+//}
+//
+//static void
+//SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
+//{
+// int res;
+// ARMword i;
+// char *local = malloc (len);
+//
+// if (local == NULL) {
+// fprintf (stderr,
+// "sim: Unable to write 0x%lx bytes - out of memory\n",
+// (long unsigned int) len);
+// return;
+// }
+//
+// for (i = 0; i < len; i++){
+// //local[i] = ARMul_ReadByte (state, ptr + i);
+// ARMword data;
+// mem_read(8, ptr + i, &data);
+// local[i] = data & 0xFF;
+// }
+//
+// res = write (f, local, len);
+// //state->Reg[0] = res == -1 ? -1 : len - res;
+// state->Reg[0] = res;
+// free (local);
+//}
+
+//static void
+//SWIflen (ARMul_State * state, ARMword fh)
+//{
+// ARMword addr;
+//
+// if (fh == 0 || fh > FOPEN_MAX) {
+// state->Reg[0] = -1L;
+// return;
+// }
+//
+// addr = lseek (fh, 0, SEEK_CUR);
+//
+// state->Reg[0] = lseek (fh, 0L, SEEK_END);
+// (void) lseek (fh, addr, SEEK_SET);
+//
+//}
+
+/***************************************************************************\
+* The emulator calls this routine when a SWI instruction is encuntered. The *
+* parameter passed is the SWI number (lower 24 bits of the instruction). *
+\***************************************************************************/
+/* ahe-ykl information is retrieved from elf header and the starting value of
+ brk_static is in sky_info_t */
+
+/* brk static hold the value of brk */
+static uint32_t brk_static = -1;
+
+unsigned
+ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
+{
+ number &= 0xfffff;
+ ARMword addr, temp;
+
+ switch (number) {
+// case SWI_Syscall:
+// if (state->Reg[7] != 0)
+// return ARMul_OSHandleSWI(state, state->Reg[7]);
+// else
+// return FALSE;
+// case SWI_Read:
+// SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
+// return TRUE;
+//
+// case SWI_GetUID32:
+// state->Reg[0] = getuid();
+// return TRUE;
+//
+// case SWI_GetGID32:
+// state->Reg[0] = getgid();
+// return TRUE;
+//
+// case SWI_GetEUID32:
+// state->Reg[0] = geteuid();
+// return TRUE;
+//
+// case SWI_GetEGID32:
+// state->Reg[0] = getegid();
+// return TRUE;
+//
+// case SWI_Write:
+// SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
+// return TRUE;
+//
+// case SWI_Open:
+// SWIopen (state, state->Reg[0], state->Reg[1]);
+// return TRUE;
+//
+// case SWI_Close:
+// state->Reg[0] = close (state->Reg[0]);
+// return TRUE;
+//
+// case SWI_Seek:{
+// /* We must return non-zero for failure */
+// state->Reg[0] =
+// lseek (state->Reg[0], state->Reg[1],
+// SEEK_SET);
+// return TRUE;
+// }
+//
+// case SWI_ExitGroup:
+// case SWI_Exit:
+// {
+// struct timeval tv;
+// //gettimeofday(&tv,NULL);
+// //printf("In %s, %d sec, %d usec\n", __FUNCTION__, tv.tv_sec, tv.tv_usec);
+// printf("passed %d sec, %lld usec\n", get_clock_sec(), get_clock_us());
+//
+// /* quit here */
+// run_command("quit");
+// return TRUE;
+// }
+// case SWI_Times:{
+// uint32_t dest = state->Reg[0];
+// struct tms now;
+// struct target_tms32 nowret;
+//
+// uint32_t ret = times(&now);
+//
+// if (ret == -1){
+// debug("syscall %s error %d\n", "SWI_Times", ret);
+// state->Reg[0] = ret;
+// return FALSE;
+// }
+//
+// nowret.tms_cstime = now.tms_cstime;
+// nowret.tms_cutime = now.tms_cutime;
+// nowret.tms_stime = now.tms_stime;
+// nowret.tms_utime = now.tms_utime;
+//
+// uint32_t offset;
+// for (offset = 0; offset < sizeof(nowret); offset++) {
+// bus_write(8, dest + offset, *((uint8_t *) &nowret + offset));
+// }
+//
+// state->Reg[0] = ret;
+// return TRUE;
+// }
+//
+// case SWI_Gettimeofday: {
+// uint32_t dest1 = state->Reg[0];
+// uint32_t dest2 = state->Reg[1]; // Unsure of this
+// struct timeval val;
+// struct timezone zone;
+// struct target_timeval32 valret;
+// struct target_timezone32 zoneret;
+//
+// uint32_t ret = gettimeofday(&val, &zone);
+// valret.tv_sec = val.tv_sec;
+// valret.tv_usec = val.tv_usec;
+// zoneret.tz_dsttime = zoneret.tz_dsttime;
+// zoneret.tz_minuteswest = zoneret.tz_minuteswest;
+//
+// if (ret == -1){
+// debug("syscall %s error %d\n", "SWI_Gettimeofday", ret);
+// state->Reg[0] = ret;
+// return FALSE;
+// }
+//
+// uint32_t offset;
+// if (dest1) {
+// for (offset = 0; offset < sizeof(valret); offset++) {
+// bus_write(8, dest1 + offset, *((uint8_t *) &valret + offset));
+// }
+// state->Reg[0] = ret;
+// }
+// if (dest2) {
+// for (offset = 0; offset < sizeof(zoneret); offset++) {
+// bus_write(8, dest2 + offset, *((uint8_t *) &zoneret + offset));
+// }
+// state->Reg[0] = ret;
+// }
+//
+// return TRUE;
+// }
+// case SWI_Brk:
+// /* initialize brk value */
+// /* suppose that brk_static doesn't reach 0xffffffff... */
+// if (brk_static == -1) {
+// brk_static = (get_skyeye_pref()->info).brk;
+// }
+//
+// /* FIXME there might be a need to do a mmap */
+//
+// if(state->Reg[0]){
+// if (get_skyeye_exec_info()->mmap_access) {
+// /* if new brk is greater than current brk, allocate memory */
+// if (state->Reg[0] > brk_static) {
+// uint32_t ret = mmap( (void *) brk_static, state->Reg[0] - brk_static,
+// PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0 );
+// if (ret != MAP_FAILED)
+// brk_static = ret;
+// }
+// }
+// brk_static = state->Reg[0];
+// //state->Reg[0] = 0; /* FIXME return value of brk set to be the address on success */
+// } else {
+// state->Reg[0] = brk_static;
+// }
+// return TRUE;
+//
+// case SWI_Break:
+// state->Emulate = FALSE;
+// return TRUE;
+//
+// case SWI_Mmap:{
+// int addr = state->Reg[0];
+// int len = state->Reg[1];
+// int prot = state->Reg[2];
+// int flag = state->Reg[3];
+// int fd = state->Reg[4];
+// int offset = state->Reg[5];
+// mmap_area_t *area = new_mmap_area(addr, len);
+// state->Reg[0] = area->bank.addr;
+// //printf("syscall %d mmap(0x%x,%x,0x%x,0x%x,%d,0x%x) = 0x%x\n",\
+// SWI_Mmap, addr, len, prot, flag, fd, offset, state->Reg[0]);
+// return TRUE;
+// }
+//
+// case SWI_Munmap:
+// state->Reg[0] = 0;
+// return TRUE;
+//
+// case SWI_Mmap2:{
+// int addr = state->Reg[0];
+// int len = state->Reg[1];
+// int prot = state->Reg[2];
+// int flag = state->Reg[3];
+// int fd = state->Reg[4];
+// int offset = state->Reg[5] * 4096; /* page offset */
+// mmap_area_t *area = new_mmap_area(addr, len);
+// state->Reg[0] = area->bank.addr;
+//
+// return TRUE;
+// }
+//
+// case SWI_Breakpoint:
+// //chy 2005-09-12 change below line
+// //state->EndCondition = RDIError_BreakpointReached;
+// //printf ("SKYEYE: in armos.c : should not come here!!!!\n");
+// state->EndCondition = 0;
+// /*modified by ksh to support breakpoiont*/
+// state->Emulate = STOP;
+// return (TRUE);
+// case SWI_Uname:
+// {
+// struct utsname *uts = (uintptr_t) state->Reg[0]; /* uname should write data in this address */
+// struct utsname utsbuf;
+// //printf("Uname size is %x\n", sizeof(utsbuf));
+// char *buf;
+// uintptr_t sp ; /* used as a temporary address */
+//
+//#define COPY_UTS_STRING(addr) \
+// buf = addr; \
+// while(*buf != NULL) { \
+// bus_write(8, sp, *buf); \
+// sp++; \
+// buf++; \
+// }
+//#define COPY_UTS(field) /*printf("%s: %s at %p\n", #field, utsbuf.field, uts->field);*/ \
+// sp = (uintptr_t) uts->field; \
+// COPY_UTS_STRING((&utsbuf)->field);
+//
+// if (uname(&utsbuf) < 0) {
+// printf("syscall uname: utsname error\n");
+// state->Reg[0] = -1;
+// return FALSE;
+// }
+//
+// /* FIXME for now, this is just the host system call
+// Some data should be missing, as it depends on
+// the version of utsname */
+// COPY_UTS(sysname);
+// COPY_UTS(nodename);
+// COPY_UTS(release);
+// COPY_UTS(version);
+// COPY_UTS(machine);
+//
+// state->Reg[0] = 0;
+// return TRUE;
+// }
+// case SWI_Fcntl:
+// {
+// uint32_t fd = state->Reg[0];
+// uint32_t cmd = state->Reg[1];
+// uint32_t arg = state->Reg[2];
+// uint32_t ret;
+//
+// switch(cmd){
+// case (F_GETFD):
+// {
+// ret = fcntl(fd, cmd, arg);
+// //printf("syscall fcntl for getfd not implemented, ret %d\n", ret);
+// state->Reg[0] = ret;
+// return FALSE;
+// }
+// default:
+// break;
+// }
+//
+// printf("syscall fcntl unimplemented fd %x cmd %x\n", fd, cmd);
+// state->Reg[0] = -1;
+// return FALSE;
+//
+// }
+// case SWI_Fstat64:
+// {
+// uint32_t dest = state->Reg[1];
+// uint32_t fd = state->Reg[0];
+// struct stat64 statbuf;
+// struct target_stat64 statret;
+// memset(&statret, 0, sizeof(struct target_stat64));
+// uint32_t ret = fstat64(fd, &statbuf);
+//
+// if (ret == -1){
+// printf("syscall %s returned error\n", "SWI_Fstat");
+// state->Reg[0] = ret;
+// return FALSE;
+// }
+//
+// /* copy statbuf to the process memory space
+// FIXME can't say if endian has an effect here */
+// uint32_t offset;
+// //printf("Fstat system is size %x\n", sizeof(statbuf));
+// //printf("Fstat target is size %x\n", sizeof(statret));
+//
+// /* we copy system structure data stat64 into arm fixed size structure target_stat64 */
+// statret.st_dev = statbuf.st_dev;
+// statret.st_ino = statbuf.st_ino;
+// statret.st_mode = statbuf.st_mode;
+// statret.st_nlink = statbuf.st_nlink;
+// statret.st_uid = statbuf.st_uid;
+// statret.st_gid = statbuf.st_gid;
+// statret.st_rdev = statbuf.st_rdev;
+// statret.st_size = statbuf.st_size;
+// statret.st_blksize = statbuf.st_blksize;
+// statret.st_blocks = statbuf.st_blocks;
+// statret.st32_atime = statbuf.st_atime;
+// statret.st32_mtime = statbuf.st_mtime;
+// statret.st32_ctime = statbuf.st_ctime;
+//
+// for (offset = 0; offset < sizeof(statret); offset++) {
+// bus_write(8, dest + offset, *((uint8_t *) &statret + offset));
+// }
+//
+// state->Reg[0] = ret;
+// return TRUE;
+// }
+// case SWI_Set_tls:
+// {
+// //printf("syscall set_tls unimplemented\n");
+// state->mmu.thread_uro_id = state->Reg[0];
+// state->CP15[CP15_THREAD_URO - CP15_BASE] = state->Reg[0];
+// state->Reg[0] = 0;
+// return FALSE;
+// }
+//#if 0
+// case SWI_Clock:
+// /* return number of centi-seconds... */
+// state->Reg[0] =
+//#ifdef CLOCKS_PER_SEC
+// (CLOCKS_PER_SEC >= 100)
+// ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
+// : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
+//#else
+// /* presume unix... clock() returns microseconds */
+// (ARMword) (clock () / 10000);
+//#endif
+// return (TRUE);
+//
+// case SWI_Time:
+// state->Reg[0] = (ARMword) time (NULL);
+// return (TRUE);
+// case SWI_Flen:
+// SWIflen (state, state->Reg[0]);
+// return (TRUE);
+//
+//#endif
+ default:
+
+ _dbg_assert_msg_(ARM11, false, "ImplementMe: ARMul_OSHandleSWI!");
+
+ return (FALSE);
+ }
+}
+//
+///**
+// * @brief For mmap syscall.A mmap_area is a memory bank. Get from ppc.
+// */
+//static mmap_area_t* new_mmap_area(int sim_addr, int len){
+// mmap_area_t *area = (mmap_area_t *)malloc(sizeof(mmap_area_t));
+// if(area == NULL){
+// printf("error, failed %s\n",__FUNCTION__);
+// exit(0);
+// }
+//#if FAST_MEMORY
+// if (mmap_next_base == -1)
+// {
+// mmap_next_base = get_skyeye_exec_info()->brk;
+// }
+//#endif
+//
+// memset(area, 0x0, sizeof(mmap_area_t));
+// area->bank.addr = mmap_next_base;
+// area->bank.len = len;
+// area->bank.bank_write = mmap_mem_write;
+// area->bank.bank_read = mmap_mem_read;
+// area->bank.type = MEMTYPE_RAM;
+// area->bank.objname = "mmap";
+// addr_mapping(&area->bank);
+//
+//#if FAST_MEMORY
+// if (get_skyeye_exec_info()->mmap_access)
+// {
+// /* FIXME check proper flags */
+// /* FIXME we may delete the need of banks up there */
+// uint32_t ret = mmap(mmap_next_base, len, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+// mmap_next_base = ret;
+// }
+// area->mmap_addr = (uint8_t*)get_dma_addr(mmap_next_base);
+//#else
+// area->mmap_addr = malloc(len);
+// if(area->mmap_addr == NULL){
+// printf("error mmap malloc\n");
+// exit(0);
+// }
+// memset(area->mmap_addr, 0x0, len);
+//#endif
+//
+// area->next = NULL;
+// if(mmap_global){
+// area->next = mmap_global->next;
+// mmap_global->next = area;
+// }else{
+// mmap_global = area;
+// }
+// mmap_next_base = mmap_next_base + len;
+// return area;
+//}
+//
+//static mmap_area_t *get_mmap_area(int addr){
+// mmap_area_t *tmp = mmap_global;
+// while(tmp){
+// if ((tmp->bank.addr <= addr) && (tmp->bank.addr + tmp->bank.len > addr)){
+// return tmp;
+// }
+// tmp = tmp->next;
+// }
+// printf("cannot get mmap area:addr=0x%x\n", addr);
+// return NULL;
+//}
+//
+///**
+// * @brief the mmap_area bank write function. Get from ppc.
+// *
+// * @param size size to write, 8/16/32
+// * @param addr address to write
+// * @param value value to write
+// *
+// * @return sucess return 1,otherwise 0.
+// */
+//static char mmap_mem_write(short size, int addr, uint32_t value){
+// mmap_area_t *area_tmp = get_mmap_area(addr);
+// mem_bank_t *bank_tmp = &area_tmp->bank;
+// int offset = addr - bank_tmp->addr;
+// switch(size){
+// case 8:{
+// //uint8_t value_endian = value;
+// uint8_t value_endian = (uint8_t)value;
+// *(uint8_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
+// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
+// break;
+// }
+// case 16:{
+// //uint16_t value_endian = half_to_BE((uint16_t)value);
+// uint16_t value_endian = ((uint16_t)value);
+// *(uint16_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
+// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
+// break;
+// }
+// case 32:{
+// //uint32_t value_endian = word_to_BE((uint32_t)value);
+// uint32_t value_endian = ((uint32_t)value);
+// *(uint32_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
+// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
+// break;
+// }
+// default:
+// printf("invalid size %d\n",size);
+// return 0;
+// }
+// return 1;
+//}
+//
+///**
+// * @brief the mmap_area bank read function. Get from ppc.
+// *
+// * @param size size to read, 8/16/32
+// * @param addr address to read
+// * @param value value to read
+// *
+// * @return sucess return 1,otherwise 0.
+// */
+//static char mmap_mem_read(short size, int addr, uint32_t * value){
+// mmap_area_t *area_tmp = get_mmap_area(addr);
+// mem_bank_t *bank_tmp = &area_tmp->bank;
+// int offset = addr - bank_tmp->addr;
+// switch(size){
+// case 8:{
+// //*(uint8_t *)value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
+// *value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
+// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
+// break;
+// }
+// case 16:{
+// //*(uint16_t *)value = half_from_BE(*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
+// *value = (*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
+// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint16_t*)value);
+// break;
+// }
+// case 32:
+// //*value = (uint32_t)word_from_BE(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
+// *value = (uint32_t)(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
+// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
+// break;
+// default:
+// printf("invalid size %d\n",size);
+// return 0;
+// }
+// return 1;
+//}
diff --git a/src/core/src/arm/armsupp.cpp b/src/core/src/arm/armsupp.cpp
new file mode 100644
index 000000000..c2b8399c9
--- /dev/null
+++ b/src/core/src/arm/armsupp.cpp
@@ -0,0 +1,953 @@
+/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator.
+ Copyright (C) 1994 Advanced RISC Machines Ltd.
+
+ 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 "armdefs.h"
+#include "armemu.h"
+//#include "ansidecl.h"
+#include "skyeye_defs.h"
+unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
+ unsigned cpnum);
+//extern int skyeye_instr_debug;
+/* Definitions for the support routines. */
+
+static ARMword ModeToBank (ARMword);
+static void EnvokeList (ARMul_State *, unsigned int, unsigned int);
+
+struct EventNode
+{ /* An event list node. */
+ unsigned (*func) (ARMul_State *); /* The function to call. */
+ struct EventNode *next;
+};
+
+/* This routine returns the value of a register from a mode. */
+
+ARMword
+ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
+{
+ mode &= MODEBITS;
+ if (mode != state->Mode)
+ return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
+ else
+ return (state->Reg[reg]);
+}
+
+/* This routine sets the value of a register for a mode. */
+
+void
+ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
+{
+ mode &= MODEBITS;
+ if (mode != state->Mode)
+ state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
+ else
+ state->Reg[reg] = value;
+}
+
+/* This routine returns the value of the PC, mode independently. */
+
+ARMword
+ARMul_GetPC (ARMul_State * state)
+{
+ if (state->Mode > SVC26MODE)
+ return state->Reg[15];
+ else
+ return R15PC;
+}
+
+/* This routine returns the value of the PC, mode independently. */
+
+ARMword
+ARMul_GetNextPC (ARMul_State * state)
+{
+ if (state->Mode > SVC26MODE)
+ return state->Reg[15] + isize;
+ else
+ return (state->Reg[15] + isize) & R15PCBITS;
+}
+
+/* This routine sets the value of the PC. */
+
+void
+ARMul_SetPC (ARMul_State * state, ARMword value)
+{
+ if (ARMul_MODE32BIT)
+ state->Reg[15] = value & PCBITS;
+ else
+ state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
+ FLUSHPIPE;
+}
+
+/* This routine returns the value of register 15, mode independently. */
+
+ARMword
+ARMul_GetR15 (ARMul_State * state)
+{
+ if (state->Mode > SVC26MODE)
+ return (state->Reg[15]);
+ else
+ return (R15PC | ECC | ER15INT | EMODE);
+}
+
+/* This routine sets the value of Register 15. */
+
+void
+ARMul_SetR15 (ARMul_State * state, ARMword value)
+{
+ if (ARMul_MODE32BIT)
+ state->Reg[15] = value & PCBITS;
+ else {
+ state->Reg[15] = value;
+ ARMul_R15Altered (state);
+ }
+ FLUSHPIPE;
+}
+
+/* This routine returns the value of the CPSR. */
+
+ARMword
+ARMul_GetCPSR (ARMul_State * state)
+{
+ //chy 2003-08-20: below is from gdb20030716, maybe isn't suitable for system simulator
+ //return (CPSR | state->Cpsr); for gdb20030716
+ return (CPSR); //had be tested in old skyeye with gdb5.0-5.3
+}
+
+/* This routine sets the value of the CPSR. */
+
+void
+ARMul_SetCPSR (ARMul_State * state, ARMword value)
+{
+ state->Cpsr = value;
+ ARMul_CPSRAltered (state);
+}
+
+/* This routine does all the nasty bits involved in a write to the CPSR,
+ including updating the register bank, given a MSR instruction. */
+
+void
+ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
+{
+ state->Cpsr = ARMul_GetCPSR (state);
+ //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
+ if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
+ /* In user mode, only write flags. */
+ if (BIT (16))
+ SETPSR_C (state->Cpsr, rhs);
+ if (BIT (17))
+ SETPSR_X (state->Cpsr, rhs);
+ if (BIT (18))
+ SETPSR_S (state->Cpsr, rhs);
+ }
+ if (BIT (19))
+ SETPSR_F (state->Cpsr, rhs);
+ ARMul_CPSRAltered (state);
+}
+
+/* Get an SPSR from the specified mode. */
+
+ARMword
+ARMul_GetSPSR (ARMul_State * state, ARMword mode)
+{
+ ARMword bank = ModeToBank (mode & MODEBITS);
+
+ if (!BANK_CAN_ACCESS_SPSR (bank))
+ return ARMul_GetCPSR (state);
+
+ return state->Spsr[bank];
+}
+
+/* This routine does a write to an SPSR. */
+
+void
+ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
+{
+ ARMword bank = ModeToBank (mode & MODEBITS);
+
+ if (BANK_CAN_ACCESS_SPSR (bank))
+ state->Spsr[bank] = value;
+}
+
+/* This routine does a write to the current SPSR, given an MSR instruction. */
+
+void
+ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
+{
+ if (BANK_CAN_ACCESS_SPSR (state->Bank)) {
+ if (BIT (16))
+ SETPSR_C (state->Spsr[state->Bank], rhs);
+ if (BIT (17))
+ SETPSR_X (state->Spsr[state->Bank], rhs);
+ if (BIT (18))
+ SETPSR_S (state->Spsr[state->Bank], rhs);
+ if (BIT (19))
+ SETPSR_F (state->Spsr[state->Bank], rhs);
+ }
+}
+
+/* This routine updates the state of the emulator after the Cpsr has been
+ changed. Both the processor flags and register bank are updated. */
+
+void
+ARMul_CPSRAltered (ARMul_State * state)
+{
+ ARMword oldmode;
+
+ if (state->prog32Sig == LOW)
+ state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
+
+ oldmode = state->Mode;
+
+ if (state->Mode != (state->Cpsr & MODEBITS)) {
+ state->Mode =
+ ARMul_SwitchMode (state, state->Mode,
+ state->Cpsr & MODEBITS);
+
+ state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
+ }
+ //state->Cpsr &= ~MODEBITS;
+
+ ASSIGNINT (state->Cpsr & INTBITS);
+ //state->Cpsr &= ~INTBITS;
+ ASSIGNN ((state->Cpsr & NBIT) != 0);
+ //state->Cpsr &= ~NBIT;
+ ASSIGNZ ((state->Cpsr & ZBIT) != 0);
+ //state->Cpsr &= ~ZBIT;
+ ASSIGNC ((state->Cpsr & CBIT) != 0);
+ //state->Cpsr &= ~CBIT;
+ ASSIGNV ((state->Cpsr & VBIT) != 0);
+ //state->Cpsr &= ~VBIT;
+ ASSIGNS ((state->Cpsr & SBIT) != 0);
+ //state->Cpsr &= ~SBIT;
+#ifdef MODET
+ ASSIGNT ((state->Cpsr & TBIT) != 0);
+ //state->Cpsr &= ~TBIT;
+#endif
+
+ if (oldmode > SVC26MODE) {
+ if (state->Mode <= SVC26MODE) {
+ state->Emulate = CHANGEMODE;
+ state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
+ }
+ }
+ else {
+ if (state->Mode > SVC26MODE) {
+ state->Emulate = CHANGEMODE;
+ state->Reg[15] = R15PC;
+ }
+ else
+ state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
+ }
+}
+
+/* This routine updates the state of the emulator after register 15 has
+ been changed. Both the processor flags and register bank are updated.
+ This routine should only be called from a 26 bit mode. */
+
+void
+ARMul_R15Altered (ARMul_State * state)
+{
+ if (state->Mode != R15MODE) {
+ state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
+ state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
+ }
+
+ if (state->Mode > SVC26MODE)
+ state->Emulate = CHANGEMODE;
+
+ ASSIGNR15INT (R15INT);
+
+ ASSIGNN ((state->Reg[15] & NBIT) != 0);
+ ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
+ ASSIGNC ((state->Reg[15] & CBIT) != 0);
+ ASSIGNV ((state->Reg[15] & VBIT) != 0);
+}
+
+/* This routine controls the saving and restoring of registers across mode
+ changes. The regbank matrix is largely unused, only rows 13 and 14 are
+ used across all modes, 8 to 14 are used for FIQ, all others use the USER
+ column. It's easier this way. old and new parameter are modes numbers.
+ Notice the side effect of changing the Bank variable. */
+
+ARMword
+ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
+{
+ unsigned i;
+ ARMword oldbank;
+ ARMword newbank;
+ static int revision_value = 53;
+
+ oldbank = ModeToBank (oldmode);
+ newbank = state->Bank = ModeToBank (newmode);
+
+ /* Do we really need to do it? */
+ if (oldbank != newbank) {
+ if (oldbank == 3 && newbank == 2) {
+ //printf("icounter is %d PC is %x MODE CHANGED : %d --> %d\n", state->NumInstrs, state->pc, oldbank, newbank);
+ if (state->NumInstrs >= 5832487) {
+// printf("%d, ", state->NumInstrs + revision_value);
+// printf("revision_value : %d\n", revision_value);
+ revision_value ++;
+ }
+ }
+ /* Save away the old registers. */
+ switch (oldbank) {
+ case USERBANK:
+ case IRQBANK:
+ case SVCBANK:
+ case ABORTBANK:
+ case UNDEFBANK:
+ if (newbank == FIQBANK)
+ for (i = 8; i < 13; i++)
+ state->RegBank[USERBANK][i] =
+ state->Reg[i];
+ state->RegBank[oldbank][13] = state->Reg[13];
+ state->RegBank[oldbank][14] = state->Reg[14];
+ break;
+ case FIQBANK:
+ for (i = 8; i < 15; i++)
+ state->RegBank[FIQBANK][i] = state->Reg[i];
+ break;
+ case DUMMYBANK:
+ for (i = 8; i < 15; i++)
+ state->RegBank[DUMMYBANK][i] = 0;
+ break;
+ default:
+ abort ();
+ }
+
+ /* Restore the new registers. */
+ switch (newbank) {
+ case USERBANK:
+ case IRQBANK:
+ case SVCBANK:
+ case ABORTBANK:
+ case UNDEFBANK:
+ if (oldbank == FIQBANK)
+ for (i = 8; i < 13; i++)
+ state->Reg[i] =
+ state->RegBank[USERBANK][i];
+ state->Reg[13] = state->RegBank[newbank][13];
+ state->Reg[14] = state->RegBank[newbank][14];
+ break;
+ case FIQBANK:
+ for (i = 8; i < 15; i++)
+ state->Reg[i] = state->RegBank[FIQBANK][i];
+ break;
+ case DUMMYBANK:
+ for (i = 8; i < 15; i++)
+ state->Reg[i] = 0;
+ break;
+ default:
+ abort ();
+ }
+ }
+
+ return newmode;
+}
+
+/* Given a processor mode, this routine returns the
+ register bank that will be accessed in that mode. */
+
+static ARMword
+ModeToBank (ARMword mode)
+{
+ static ARMword bankofmode[] = {
+ USERBANK, FIQBANK, IRQBANK, SVCBANK,
+ DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
+ DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
+ DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
+ USERBANK, FIQBANK, IRQBANK, SVCBANK,
+ DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
+ DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
+ DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
+ };
+
+ if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
+ return DUMMYBANK;
+
+ return bankofmode[mode];
+}
+
+/* Returns the register number of the nth register in a reg list. */
+
+unsigned
+ARMul_NthReg (ARMword instr, unsigned number)
+{
+ unsigned bit, upto;
+
+ for (bit = 0, upto = 0; upto <= number; bit++)
+ if (BIT (bit))
+ upto++;
+
+ return (bit - 1);
+}
+
+/* Assigns the N and Z flags depending on the value of result. */
+
+void
+ARMul_NegZero (ARMul_State * state, ARMword result)
+{
+ if (NEG (result)) {
+ SETN;
+ CLEARZ;
+ }
+ else if (result == 0) {
+ CLEARN;
+ SETZ;
+ }
+ else {
+ CLEARN;
+ CLEARZ;
+ }
+}
+
+/* Compute whether an addition of A and B, giving RESULT, overflowed. */
+
+int
+AddOverflow (ARMword a, ARMword b, ARMword result)
+{
+ return ((NEG (a) && NEG (b) && POS (result))
+ || (POS (a) && POS (b) && NEG (result)));
+}
+
+/* Compute whether a subtraction of A and B, giving RESULT, overflowed. */
+
+int
+SubOverflow (ARMword a, ARMword b, ARMword result)
+{
+ return ((NEG (a) && POS (b) && POS (result))
+ || (POS (a) && NEG (b) && NEG (result)));
+}
+
+/* Assigns the C flag after an addition of a and b to give result. */
+
+void
+ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
+{
+ ASSIGNC ((NEG (a) && NEG (b)) ||
+ (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
+}
+
+/* Assigns the V flag after an addition of a and b to give result. */
+
+void
+ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
+{
+ ASSIGNV (AddOverflow (a, b, result));
+}
+
+/* Assigns the C flag after an subtraction of a and b to give result. */
+
+void
+ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
+{
+ ASSIGNC ((NEG (a) && POS (b)) ||
+ (NEG (a) && POS (result)) || (POS (b) && POS (result)));
+}
+
+/* Assigns the V flag after an subtraction of a and b to give result. */
+
+void
+ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
+{
+ ASSIGNV (SubOverflow (a, b, result));
+}
+
+/* This function does the work of generating the addresses used in an
+ LDC instruction. The code here is always post-indexed, it's up to the
+ caller to get the input address correct and to handle base register
+ modification. It also handles the Busy-Waiting. */
+
+void
+ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
+{
+ unsigned cpab;
+ ARMword data;
+
+ UNDEF_LSCPCBaseWb;
+ //printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
+/*chy 2004-05-23 should update this function in the future,should concern dataabort*/
+// chy 2004-05-25 , fix it now,so needn't printf
+// printf("SKYEYE ARMul_LDC, should update this function!!!!!\n");
+ //exit(-1);
+
+ if (!CP_ACCESS_ALLOWED (state, CPNum)) {
+ /*
+ printf
+ ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n",
+ CPNum, instr, address);
+ */
+ ARMul_UndefInstr (state, instr);
+ return;
+ }
+
+ if (ADDREXCEPT (address))
+ INTERNALABORT (address);
+
+ cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
+ while (cpab == ARMul_BUSY) {
+ ARMul_Icycles (state, 1, 0);
+
+ if (IntPending (state)) {
+ cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT,
+ instr, 0);
+ return;
+ }
+ else
+ cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr,
+ 0);
+ }
+ if (cpab == ARMul_CANT) {
+ /*
+ printf
+ ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n",
+ CPNum, instr, address);
+ */
+ CPTAKEABORT;
+ return;
+ }
+
+ cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
+ data = ARMul_LoadWordN (state, address);
+ //chy 2004-05-25
+ if (state->abortSig || state->Aborted)
+ goto L_ldc_takeabort;
+
+ BUSUSEDINCPCN;
+//chy 2004-05-25
+/*
+ if (BIT (21))
+ LSBase = state->Base;
+*/
+
+ cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
+
+ while (cpab == ARMul_INC) {
+ address += 4;
+ data = ARMul_LoadWordN (state, address);
+ //chy 2004-05-25
+ if (state->abortSig || state->Aborted)
+ goto L_ldc_takeabort;
+
+ cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
+ }
+
+//chy 2004-05-25
+ L_ldc_takeabort:
+ if (BIT (21)) {
+ if (!
+ ((state->abortSig || state->Aborted)
+ && state->lateabtSig == LOW))
+ LSBase = state->Base;
+ }
+
+ if (state->abortSig || state->Aborted)
+ TAKEABORT;
+}
+
+/* This function does the work of generating the addresses used in an
+ STC instruction. The code here is always post-indexed, it's up to the
+ caller to get the input address correct and to handle base register
+ modification. It also handles the Busy-Waiting. */
+
+void
+ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
+{
+ unsigned cpab;
+ ARMword data;
+
+ UNDEF_LSCPCBaseWb;
+
+ //printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
+ /*chy 2004-05-23 should update this function in the future,should concern dataabort */
+// skyeye_instr_debug=0;printf("SKYEYE debug end!!!!\n");
+// chy 2004-05-25 , fix it now,so needn't printf
+// printf("SKYEYE ARMul_STC, should update this function!!!!!\n");
+
+ //exit(-1);
+ if (!CP_ACCESS_ALLOWED (state, CPNum)) {
+ /*
+ printf
+ ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr, CPnum is %x, instr %x, addr %x\n",
+ CPNum, instr, address);
+ */
+ ARMul_UndefInstr (state, instr);
+ return;
+ }
+
+ if (ADDREXCEPT (address) || VECTORACCESS (address))
+ INTERNALABORT (address);
+
+ cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
+ while (cpab == ARMul_BUSY) {
+ ARMul_Icycles (state, 1, 0);
+ if (IntPending (state)) {
+ cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT,
+ instr, 0);
+ return;
+ }
+ else
+ cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr,
+ &data);
+ }
+
+ if (cpab == ARMul_CANT) {
+ /*
+ printf
+ ("SKYEYE ARMul_STC,CANT, undefinstr, CPnum is %x, instr %x, addr %x\n",
+ CPNum, instr, address);
+ */
+ CPTAKEABORT;
+ return;
+ }
+#ifndef MODE32
+ if (ADDREXCEPT (address) || VECTORACCESS (address))
+ INTERNALABORT (address);
+#endif
+ BUSUSEDINCPCN;
+//chy 2004-05-25
+/*
+ if (BIT (21))
+ LSBase = state->Base;
+*/
+ cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
+ ARMul_StoreWordN (state, address, data);
+ //chy 2004-05-25
+ if (state->abortSig || state->Aborted)
+ goto L_stc_takeabort;
+
+ while (cpab == ARMul_INC) {
+ address += 4;
+ cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
+ ARMul_StoreWordN (state, address, data);
+ //chy 2004-05-25
+ if (state->abortSig || state->Aborted)
+ goto L_stc_takeabort;
+ }
+//chy 2004-05-25
+ L_stc_takeabort:
+ if (BIT (21)) {
+ if (!
+ ((state->abortSig || state->Aborted)
+ && state->lateabtSig == LOW))
+ LSBase = state->Base;
+ }
+
+ if (state->abortSig || state->Aborted)
+ TAKEABORT;
+}
+
+/* This function does the Busy-Waiting for an MCR instruction. */
+
+void
+ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
+{
+ unsigned cpab;
+
+ //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source);
+ if (!CP_ACCESS_ALLOWED (state, CPNum)) {
+ //chy 2004-07-19 should fix in the future ????!!!!
+ //printf("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source);
+ ARMul_UndefInstr (state, instr);
+ return;
+ }
+
+ cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
+
+ while (cpab == ARMul_BUSY) {
+ ARMul_Icycles (state, 1, 0);
+
+ if (IntPending (state)) {
+ cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT,
+ instr, 0);
+ return;
+ }
+ else
+ cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr,
+ source);
+ }
+
+ if (cpab == ARMul_CANT) {
+ printf ("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source);
+ ARMul_Abort (state, ARMul_UndefinedInstrV);
+ }
+ else {
+ BUSUSEDINCPCN;
+ ARMul_Ccycles (state, 1, 0);
+ }
+}
+
+/* This function does the Busy-Waiting for an MCRR instruction. */
+
+void
+ARMul_MCRR (ARMul_State * state, ARMword instr, ARMword source1, ARMword source2)
+{
+ unsigned cpab;
+
+ if (!CP_ACCESS_ALLOWED (state, CPNum)) {
+ ARMul_UndefInstr (state, instr);
+ return;
+ }
+
+ cpab = (state->MCRR[CPNum]) (state, ARMul_FIRST, instr, source1, source2);
+
+ while (cpab == ARMul_BUSY) {
+ ARMul_Icycles (state, 1, 0);
+
+ if (IntPending (state)) {
+ cpab = (state->MCRR[CPNum]) (state, ARMul_INTERRUPT,
+ instr, 0, 0);
+ return;
+ }
+ else
+ cpab = (state->MCRR[CPNum]) (state, ARMul_BUSY, instr,
+ source1, source2);
+ }
+ if (cpab == ARMul_CANT) {
+ printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x, source %x %x\n", __FUNCTION__, CPNum, instr, source1, source2);
+ ARMul_Abort (state, ARMul_UndefinedInstrV);
+ }
+ else {
+ BUSUSEDINCPCN;
+ ARMul_Ccycles (state, 1, 0);
+ }
+}
+
+/* This function does the Busy-Waiting for an MRC instruction. */
+
+ARMword
+ARMul_MRC (ARMul_State * state, ARMword instr)
+{
+ unsigned cpab;
+ ARMword result = 0;
+
+ //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
+ if (!CP_ACCESS_ALLOWED (state, CPNum)) {
+ //chy 2004-07-19 should fix in the future????!!!!
+ //printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n",CPNum, instr);
+ ARMul_UndefInstr (state, instr);
+ return -1;
+ }
+
+ cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
+ while (cpab == ARMul_BUSY) {
+ ARMul_Icycles (state, 1, 0);
+ if (IntPending (state)) {
+ cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
+ instr, 0);
+ return (0);
+ }
+ else
+ cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
+ &result);
+ }
+ if (cpab == ARMul_CANT) {
+ printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr);
+ ARMul_Abort (state, ARMul_UndefinedInstrV);
+ /* Parent will destroy the flags otherwise. */
+ result = ECC;
+ }
+ else {
+ BUSUSEDINCPCN;
+ ARMul_Ccycles (state, 1, 0);
+ ARMul_Icycles (state, 1, 0);
+ }
+
+ return result;
+}
+
+/* This function does the Busy-Waiting for an MRRC instruction. (to verify) */
+
+void
+ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2)
+{
+ unsigned cpab;
+ ARMword result1 = 0;
+ ARMword result2 = 0;
+
+ if (!CP_ACCESS_ALLOWED (state, CPNum)) {
+ ARMul_UndefInstr (state, instr);
+ return;
+ }
+
+ cpab = (state->MRRC[CPNum]) (state, ARMul_FIRST, instr, &result1, &result2);
+ while (cpab == ARMul_BUSY) {
+ ARMul_Icycles (state, 1, 0);
+ if (IntPending (state)) {
+ cpab = (state->MRRC[CPNum]) (state, ARMul_INTERRUPT,
+ instr, 0, 0);
+ return;
+ }
+ else
+ cpab = (state->MRRC[CPNum]) (state, ARMul_BUSY, instr,
+ &result1, &result2);
+ }
+ if (cpab == ARMul_CANT) {
+ printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x\n", __FUNCTION__, CPNum, instr);
+ ARMul_Abort (state, ARMul_UndefinedInstrV);
+ }
+ else {
+ BUSUSEDINCPCN;
+ ARMul_Ccycles (state, 1, 0);
+ ARMul_Icycles (state, 1, 0);
+ }
+
+ *dest1 = result1;
+ *dest2 = result2;
+}
+
+/* This function does the Busy-Waiting for an CDP instruction. */
+
+void
+ARMul_CDP (ARMul_State * state, ARMword instr)
+{
+ unsigned cpab;
+
+ if (!CP_ACCESS_ALLOWED (state, CPNum)) {
+ ARMul_UndefInstr (state, instr);
+ return;
+ }
+ cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
+ while (cpab == ARMul_BUSY) {
+ ARMul_Icycles (state, 1, 0);
+ if (IntPending (state)) {
+ cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT,
+ instr);
+ return;
+ }
+ else
+ cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
+ }
+ if (cpab == ARMul_CANT)
+ ARMul_Abort (state, ARMul_UndefinedInstrV);
+ else
+ BUSUSEDN;
+}
+
+/* This function handles Undefined instructions, as CP isntruction. */
+
+void
+ARMul_UndefInstr (ARMul_State * state, ARMword instr)
+{
+ ERROR_LOG(ARM11, "Undefined instruction!! Instr: 0x%x", instr);
+ ARMul_Abort (state, ARMul_UndefinedInstrV);
+}
+
+/* Return TRUE if an interrupt is pending, FALSE otherwise. */
+
+unsigned
+IntPending (ARMul_State * state)
+{
+ /* Any exceptions. */
+ if (state->NresetSig == LOW) {
+ ARMul_Abort (state, ARMul_ResetV);
+ return TRUE;
+ }
+ else if (!state->NfiqSig && !FFLAG) {
+ ARMul_Abort (state, ARMul_FIQV);
+ return TRUE;
+ }
+ else if (!state->NirqSig && !IFLAG) {
+ ARMul_Abort (state, ARMul_IRQV);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Align a word access to a non word boundary. */
+
+ARMword
+ARMul_Align (ARMul_State *state, ARMword address, ARMword data)
+{
+ /* This code assumes the address is really unaligned,
+ as a shift by 32 is undefined in C. */
+
+ address = (address & 3) << 3; /* Get the word address. */
+ return ((data >> address) | (data << (32 - address))); /* rot right */
+}
+
+/* This routine is used to call another routine after a certain number of
+ cycles have been executed. The first parameter is the number of cycles
+ delay before the function is called, the second argument is a pointer
+ to the function. A delay of zero doesn't work, just call the function. */
+
+void
+ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay,
+ unsigned (*what) (ARMul_State *))
+{
+ unsigned int when;
+ struct EventNode *event;
+
+ if (state->EventSet++ == 0)
+ state->Now = ARMul_Time (state);
+ when = (state->Now + delay) % EVENTLISTSIZE;
+ event = (struct EventNode *) malloc (sizeof (struct EventNode));
+
+ _dbg_assert_msg_(ARM11, event, "SKYEYE:ARMul_ScheduleEvent: malloc event error\n");
+
+ event->func = what;
+ event->next = *(state->EventPtr + when);
+ *(state->EventPtr + when) = event;
+}
+
+/* This routine is called at the beginning of
+ every cycle, to envoke scheduled events. */
+
+void
+ARMul_EnvokeEvent (ARMul_State * state)
+{
+ static unsigned int then;
+
+ then = state->Now;
+ state->Now = ARMul_Time (state) % EVENTLISTSIZE;
+ if (then < state->Now)
+ /* Schedule events. */
+ EnvokeList (state, then, state->Now);
+ else if (then > state->Now) {
+ /* Need to wrap around the list. */
+ EnvokeList (state, then, EVENTLISTSIZE - 1L);
+ EnvokeList (state, 0L, state->Now);
+ }
+}
+
+/* Envokes all the entries in a range. */
+
+static void
+EnvokeList (ARMul_State * state, unsigned int from, unsigned int to)
+{
+ for (; from <= to; from++) {
+ struct EventNode *anevent;
+
+ anevent = *(state->EventPtr + from);
+ while (anevent) {
+ (anevent->func) (state);
+ state->EventSet--;
+ anevent = anevent->next;
+ }
+ *(state->EventPtr + from) = NULL;
+ }
+}
+
+/* This routine is returns the number of clock ticks since the last reset. */
+
+unsigned int
+ARMul_Time (ARMul_State * state)
+{
+ return (state->NumScycles + state->NumNcycles +
+ state->NumIcycles + state->NumCcycles + state->NumFcycles);
+}
diff --git a/src/core/src/arm/armvirt.cpp b/src/core/src/arm/armvirt.cpp
new file mode 100644
index 000000000..a072b73be
--- /dev/null
+++ b/src/core/src/arm/armvirt.cpp
@@ -0,0 +1,680 @@
+/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator.
+ Copyright (C) 1994 Advanced RISC Machines Ltd.
+
+ 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. */
+
+/* This file contains a complete ARMulator memory model, modelling a
+"virtual memory" system. A much simpler model can be found in armfast.c,
+and that model goes faster too, but has a fixed amount of memory. This
+model's memory has 64K pages, allocated on demand from a 64K entry page
+table. The routines PutWord and GetWord implement this. Pages are never
+freed as they might be needed again. A single area of memory may be
+defined to generate aborts. */
+
+#include "armdefs.h"
+#include "skyeye_defs.h"
+//#include "code_cov.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 *
+\***************************************************************************/
+
+static fault_t
+GetWord (ARMul_State * state, ARMword address, ARMword * data)
+{
+ fault_t fault;
+
+ 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;
+}
+
+//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);
+}
+
+/***************************************************************************\
+* 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;
+}
+
+/***************************************************************************\
+* 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;
+}
+
+/***************************************************************************\
+* 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;
+}
+
+/***************************************************************************\
+* 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++;
+
+#ifdef HOURGLASS
+ if ((state->NumScycles & HOURGLASS_RATE) == 0) {
+ HOURGLASS;
+ }
+#endif
+
+ return ARMul_ReLoadInstr (state, address, isize);
+}
+
+/***************************************************************************\
+* Load Instruction, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword
+ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
+{
+ state->NumNcycles++;
+
+ return ARMul_ReLoadInstr (state, address, isize);
+}
+
+/***************************************************************************\
+* Read Word (but don't tell anyone!) *
+\***************************************************************************/
+
+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
+
+ 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;
+}
+
+/***************************************************************************\
+* Load Word, Sequential Cycle *
+\***************************************************************************/
+
+ARMword
+ARMul_LoadWordS (ARMul_State * state, ARMword address)
+{
+ state->NumScycles++;
+
+ return ARMul_ReadWord (state, address);
+}
+
+/***************************************************************************\
+* Load Word, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword
+ARMul_LoadWordN (ARMul_State * state, ARMword address)
+{
+ state->NumNcycles++;
+
+ 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;
+
+}
+
+/***************************************************************************\
+* 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_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;
+ }
+}
+
+/***************************************************************************\
+* Store Word, Sequential Cycle *
+\***************************************************************************/
+
+void
+ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
+{
+ state->NumScycles++;
+
+ ARMul_WriteWord (state, address, data);
+}
+
+/***************************************************************************\
+* Store Word, Non Sequential Cycle *
+\***************************************************************************/
+
+void
+ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
+{
+ state->NumNcycles++;
+
+ ARMul_WriteWord (state, 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;
+ }
+}
+
+//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;
+ }
+}
+
+/***************************************************************************\
+* 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);
+}
+
+/***************************************************************************\
+* 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;
+}
+
+/***************************************************************************\
+* Swap Byte, (Two Non Sequential Cycles) *
+\***************************************************************************/
+
+ARMword
+ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
+{
+ ARMword temp;
+
+ temp = ARMul_LoadByte (state, address);
+ ARMul_StoreByte (state, address, data);
+
+ return temp;
+}
+
+/***************************************************************************\
+* Count I Cycles *
+\***************************************************************************/
+
+void
+ARMul_Icycles (ARMul_State * state, unsigned number,
+ ARMword address)
+{
+ state->NumIcycles += number;
+ ARMul_CLEARABORT;
+}
+
+/***************************************************************************\
+* Count C Cycles *
+\***************************************************************************/
+
+void
+ARMul_Ccycles (ARMul_State * state, unsigned number,
+ ARMword address)
+{
+ state->NumCcycles += number;
+ ARMul_CLEARABORT;
+}