summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2014-03-29 21:53:07 -0400
committerGravatar bunnei2014-03-29 21:53:07 -0400
commit6b255111d5c130e49846b1727302111f423cb157 (patch)
tree335ba0e8c06480b4f8f777651e83525ba647317f /src/core
parentadded a GetPointer function to Memory for use with ELF loading (diff)
downloadyuzu-6b255111d5c130e49846b1727302111f423cb157.tar.gz
yuzu-6b255111d5c130e49846b1727302111f423cb157.tar.xz
yuzu-6b255111d5c130e49846b1727302111f423cb157.zip
added various arm modules from skyeye to make project link OK
Diffstat (limited to 'src/core')
-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 @@
139 <ItemGroup> 139 <ItemGroup>
140 <ClCompile Include="src\arm\armemu.cpp" /> 140 <ClCompile Include="src\arm\armemu.cpp" />
141 <ClCompile Include="src\arm\arminit.cpp" /> 141 <ClCompile Include="src\arm\arminit.cpp" />
142 <ClCompile Include="src\arm\armmmu.cpp" />
143 <ClCompile Include="src\arm\armos.cpp" />
144 <ClCompile Include="src\arm\armsupp.cpp" />
145 <ClCompile Include="src\arm\armvirt.cpp" />
142 <ClCompile Include="src\arm\disassembler\arm_disasm.cpp" /> 146 <ClCompile Include="src\arm\disassembler\arm_disasm.cpp" />
143 <ClCompile Include="src\core.cpp" /> 147 <ClCompile Include="src\core.cpp" />
144 <ClCompile Include="src\core_timing.cpp" /> 148 <ClCompile Include="src\core_timing.cpp" />
149 <ClCompile Include="src\elf\elf_reader.cpp" />
145 <ClCompile Include="src\file_sys\directory_file_system.cpp" /> 150 <ClCompile Include="src\file_sys\directory_file_system.cpp" />
146 <ClCompile Include="src\file_sys\meta_file_system.cpp" /> 151 <ClCompile Include="src\file_sys\meta_file_system.cpp" />
147 <ClCompile Include="src\loader.cpp" /> 152 <ClCompile Include="src\loader.cpp" />
@@ -165,7 +170,8 @@
165 <ClInclude Include="src\arm\skyeye_defs.h" /> 170 <ClInclude Include="src\arm\skyeye_defs.h" />
166 <ClInclude Include="src\core.h" /> 171 <ClInclude Include="src\core.h" />
167 <ClInclude Include="src\core_timing.h" /> 172 <ClInclude Include="src\core_timing.h" />
168 <ClInclude Include="src\elf\elf.h" /> 173 <ClInclude Include="src\elf\elf_reader.h" />
174 <ClInclude Include="src\elf\elf_types.h" />
169 <ClInclude Include="src\file_sys\directory_file_system.h" /> 175 <ClInclude Include="src\file_sys\directory_file_system.h" />
170 <ClInclude Include="src\file_sys\file_sys.h" /> 176 <ClInclude Include="src\file_sys\file_sys.h" />
171 <ClInclude Include="src\file_sys\meta_file_system.h" /> 177 <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 @@
22 </ClCompile> 22 </ClCompile>
23 <ClCompile Include="src\system.cpp" /> 23 <ClCompile Include="src\system.cpp" />
24 <ClCompile Include="src\core_timing.cpp" /> 24 <ClCompile Include="src\core_timing.cpp" />
25 <ClCompile Include="src\elf\elf_reader.cpp">
26 <Filter>elf</Filter>
27 </ClCompile>
28 <ClCompile Include="src\arm\armsupp.cpp">
29 <Filter>arm</Filter>
30 </ClCompile>
31 <ClCompile Include="src\arm\armvirt.cpp">
32 <Filter>arm</Filter>
33 </ClCompile>
34 <ClCompile Include="src\arm\armmmu.cpp">
35 <Filter>arm</Filter>
36 </ClCompile>
37 <ClCompile Include="src\arm\armos.cpp">
38 <Filter>arm</Filter>
39 </ClCompile>
25 </ItemGroup> 40 </ItemGroup>
26 <ItemGroup> 41 <ItemGroup>
27 <Filter Include="arm"> 42 <Filter Include="arm">
@@ -94,7 +109,10 @@
94 </ClInclude> 109 </ClInclude>
95 <ClInclude Include="src\system.h" /> 110 <ClInclude Include="src\system.h" />
96 <ClInclude Include="src\core_timing.h" /> 111 <ClInclude Include="src\core_timing.h" />
97 <ClInclude Include="src\elf\elf.h"> 112 <ClInclude Include="src\elf\elf_reader.h">
113 <Filter>elf</Filter>
114 </ClInclude>
115 <ClInclude Include="src\elf\elf_types.h">
98 <Filter>elf</Filter> 116 <Filter>elf</Filter>
99 </ClInclude> 117 </ClInclude>
100 </ItemGroup> 118 </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 @@
21#include "armemu.h" 21#include "armemu.h"
22#include "armos.h" 22#include "armos.h"
23 23
24void
25XScale_set_fsr_far(ARMul_State * state, ARMword fsr, ARMword _far)
26{
27 _dbg_assert_msg_(ARM11, false, "ImplementMe: XScale_set_fsr_far!");
28 //if (!state->is_XScale || (read_cp14_reg(10) & (1UL << 31)) == 0)
29 // return;
30 //
31 //write_cp15_reg(state, 5, 0, 0, fsr);
32 //write_cp15_reg(state, 6, 0, 0, _far);
33}
34
35#define ARMul_Debug(x,y,z) 0 // Disabling this /bunnei
36
24//#include "skyeye_callback.h" 37//#include "skyeye_callback.h"
25//#include "skyeye_bus.h" 38//#include "skyeye_bus.h"
26//#include "sim_control.h" 39//#include "sim_control.h"
@@ -2174,10 +2187,10 @@ ARMul_Emulate26 (ARMul_State * state)
2174 (state, 2187 (state,
2175 ARMul_CP15_R5_MMU_EXCPT, 2188 ARMul_CP15_R5_MMU_EXCPT,
2176 pc); 2189 pc);
2177 if (!XScale_debug_moe 2190 //if (!XScale_debug_moe
2178 (state, 2191 // (state,
2179 ARMul_CP14_R10_MOE_BT)) 2192 // ARMul_CP14_R10_MOE_BT))
2180 break; 2193 // break; // Disabled /bunnei
2181 } 2194 }
2182 2195
2183 /* Force the next instruction to be refetched. */ 2196 /* 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;
73#define ASSIGNT(res) state->TFlag = res 73#define ASSIGNT(res) state->TFlag = res
74#define INSN_SIZE (TFLAG ? 2 : 4) 74#define INSN_SIZE (TFLAG ? 2 : 4)
75#else 75#else
76#define TBIT (1L << 5)
76#define INSN_SIZE 4 77#define INSN_SIZE 4
77#define TFLAG 0 78#define TFLAG 0
78#endif 79#endif
@@ -229,12 +230,12 @@ extern ARMword isize;
229 } \ 230 } \
230 while (0) 231 while (0)
231 232
232#ifndef MODE32 233//#ifndef MODE32
233#define VECTORS 0x20 234#define VECTORS 0x20
234#define LEGALADDR 0x03ffffff 235#define LEGALADDR 0x03ffffff
235#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig) 236#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig)
236#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig) 237#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig)
237#endif 238//#endif
238 239
239#define INTERNALABORT(address) \ 240#define INTERNALABORT(address) \
240 do \ 241 do \
@@ -409,10 +410,12 @@ extern ARMword isize;
409 || (! (STATE)->is_XScale) \ 410 || (! (STATE)->is_XScale) \
410 || (read_cp15_reg (15, 0, 1) & (1 << (CP)))) 411 || (read_cp15_reg (15, 0, 1) & (1 << (CP))))
411*/ 412*/
412#define CP_ACCESS_ALLOWED(STATE, CP) \ 413//#define CP_ACCESS_ALLOWED(STATE, CP) \
413 ( ((CP) >= 14) \ 414// (((CP) >= 14) \
414 || (! (STATE)->is_XScale) \ 415// || (!(STATE)->is_XScale) \
415 || (xscale_cp15_cp_access_allowed(STATE,15,CP))) 416// || (xscale_cp15_cp_access_allowed(STATE, 15, CP)))
417
418#define CP_ACCESS_ALLOWED(STATE, CP) false // Disabled coprocessor shit /bunnei
416 419
417/* Macro to rotate n right by b bits. */ 420/* Macro to rotate n right by b bits. */
418#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b)))) 421#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
271 271
272 /* Only initialse the coprocessor support once we 272 /* Only initialse the coprocessor support once we
273 know what kind of chip we are dealing with. */ 273 know what kind of chip we are dealing with. */
274 ARMul_CoProInit (state); 274 //ARMul_CoProInit (state); Commented out /bunnei
275 275
276} 276}
277 277
@@ -318,7 +318,7 @@ ARMul_Reset (ARMul_State * state)
318 state->NumFcycles = 0; 318 state->NumFcycles = 0;
319 319
320 //fprintf(stderr,"armul_reset 3: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); 320 //fprintf(stderr,"armul_reset 3: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
321 mmu_reset (state); 321 //mmu_reset (state); Commented out /bunnei
322 //fprintf(stderr,"armul_reset 4: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); 322 //fprintf(stderr,"armul_reset 4: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
323 323
324 //mem_reset (state); /* move to memory/ram.c */ 324 //mem_reset (state); /* move to memory/ram.c */
@@ -436,7 +436,8 @@ ARMul_DoProg (ARMul_State * state)
436 } 436 }
437 437
438 else { 438 else {
439 pc = ARMul_Emulate26 (state); 439 //pc = ARMul_Emulate26 (state); Commented out /bunnei
440 ERROR_LOG(ARM11, "Unsupported ARM 26-bit Mode!");
440 } 441 }
441 //chy 2006-02-22, should test debugmode first 442 //chy 2006-02-22, should test debugmode first
442 //chy 2006-04-14, put below codes in ARMul_Emulate 443 //chy 2006-04-14, put below codes in ARMul_Emulate
@@ -489,8 +490,10 @@ ARMul_DoInstr (ARMul_State * state)
489#endif 490#endif
490 } 491 }
491 492
492 else 493 else {
493 pc = ARMul_Emulate26 (state); 494 //pc = ARMul_Emulate26 (state); Commented out /bunnei
495 ERROR_LOG(ARM11, "Unsupported ARM 26-bit Mode!");
496 }
494 497
495 return (pc); 498 return (pc);
496} 499}
@@ -501,78 +504,78 @@ ARMul_DoInstr (ARMul_State * state)
501* appropriate vector's memory address (0,4,8 ....) * 504* appropriate vector's memory address (0,4,8 ....) *
502\***************************************************************************/ 505\***************************************************************************/
503 506
504//void 507void
505//ARMul_Abort (ARMul_State * state, ARMword vector) 508ARMul_Abort (ARMul_State * state, ARMword vector)
506//{ 509{
507// ARMword temp; 510 ARMword temp;
508// int isize = INSN_SIZE; 511 int isize = INSN_SIZE;
509// int esize = (TFLAG ? 0 : 4); 512 int esize = (TFLAG ? 0 : 4);
510// int e2size = (TFLAG ? -4 : 0); 513 int e2size = (TFLAG ? -4 : 0);
511// 514
512// state->Aborted = FALSE; 515 state->Aborted = FALSE;
513// 516
514// if (state->prog32Sig) 517 if (state->prog32Sig)
515// if (ARMul_MODE26BIT) 518 if (ARMul_MODE26BIT)
516// temp = R15PC; 519 temp = R15PC;
517// else 520 else
518// temp = state->Reg[15]; 521 temp = state->Reg[15];
519// else 522 else
520// temp = R15PC | ECC | ER15INT | EMODE; 523 temp = R15PC | ECC | ER15INT | EMODE;
521// 524
522// switch (vector) { 525 switch (vector) {
523// case ARMul_ResetV: /* RESET */ 526 case ARMul_ResetV: /* RESET */
524// SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE, 527 SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE,
525// 0); 528 0);
526// break; 529 break;
527// case ARMul_UndefinedInstrV: /* Undefined Instruction */ 530 case ARMul_UndefinedInstrV: /* Undefined Instruction */
528// SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE, 531 SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE,
529// isize); 532 isize);
530// break; 533 break;
531// case ARMul_SWIV: /* Software Interrupt */ 534 case ARMul_SWIV: /* Software Interrupt */
532// SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE, 535 SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
533// isize); 536 isize);
534// break; 537 break;
535// case ARMul_PrefetchAbortV: /* Prefetch Abort */ 538 case ARMul_PrefetchAbortV: /* Prefetch Abort */
536// state->AbortAddr = 1; 539 state->AbortAddr = 1;
537// SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, 540 SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
538// esize); 541 esize);
539// break; 542 break;
540// case ARMul_DataAbortV: /* Data Abort */ 543 case ARMul_DataAbortV: /* Data Abort */
541// SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, 544 SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
542// e2size); 545 e2size);
543// break; 546 break;
544// case ARMul_AddrExceptnV: /* Address Exception */ 547 case ARMul_AddrExceptnV: /* Address Exception */
545// SETABORT (IBIT, SVC26MODE, isize); 548 SETABORT (IBIT, SVC26MODE, isize);
546// break; 549 break;
547// case ARMul_IRQV: /* IRQ */ 550 case ARMul_IRQV: /* IRQ */
548// //chy 2003-09-02 the if sentence seems no use 551 //chy 2003-09-02 the if sentence seems no use
549//#if 0 552#if 0
550// if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp) 553 if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
551// || (temp & ARMul_CP13_R0_IRQ)) 554 || (temp & ARMul_CP13_R0_IRQ))
552//#endif 555#endif
553// SETABORT (IBIT, 556 SETABORT (IBIT,
554// state->prog32Sig ? IRQ32MODE : IRQ26MODE, 557 state->prog32Sig ? IRQ32MODE : IRQ26MODE,
555// esize); 558 esize);
556// break; 559 break;
557// case ARMul_FIQV: /* FIQ */ 560 case ARMul_FIQV: /* FIQ */
558// //chy 2003-09-02 the if sentence seems no use 561 //chy 2003-09-02 the if sentence seems no use
559//#if 0 562#if 0
560// if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp) 563 if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
561// || (temp & ARMul_CP13_R0_FIQ)) 564 || (temp & ARMul_CP13_R0_FIQ))
562//#endif 565#endif
563// SETABORT (INTBITS, 566 SETABORT (INTBITS,
564// state->prog32Sig ? FIQ32MODE : FIQ26MODE, 567 state->prog32Sig ? FIQ32MODE : FIQ26MODE,
565// esize); 568 esize);
566// break; 569 break;
567// } 570 }
568// 571
569// if (ARMul_MODE32BIT) { 572 if (ARMul_MODE32BIT) {
570// if (state->mmu.control & CONTROL_VECTOR) 573 if (state->mmu.control & CONTROL_VECTOR)
571// vector += 0xffff0000; //for v4 high exception address 574 vector += 0xffff0000; //for v4 high exception address
572// if (state->vector_remap_flag) 575 if (state->vector_remap_flag)
573// vector += state->vector_remap_addr; /* support some remap function in LPC processor */ 576 vector += state->vector_remap_addr; /* support some remap function in LPC processor */
574// ARMul_SetR15 (state, vector); 577 ARMul_SetR15 (state, vector);
575// } 578 }
576// else 579 else
577// ARMul_SetR15 (state, R15CCINTMODE | vector); 580 ARMul_SetR15 (state, R15CCINTMODE | vector);
578//} 581}
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)
45 state->mmu.process_id = 0; 45 state->mmu.process_id = 0;
46 46
47 switch (state->cpu->cpu_val & state->cpu->cpu_mask) { 47 switch (state->cpu->cpu_val & state->cpu->cpu_mask) {
48 case SA1100: 48 //case SA1100:
49 case SA1110: 49 //case SA1110:
50 SKYEYE_INFO("SKYEYE: use sa11xx mmu ops\n"); 50 // NOTICE_LOG(ARM11, "SKYEYE: use sa11xx mmu ops\n");
51 state->mmu.ops = sa_mmu_ops; 51 // state->mmu.ops = sa_mmu_ops;
52 break; 52 // break;
53 case PXA250: 53 //case PXA250:
54 case PXA270: //xscale 54 //case PXA270: //xscale
55 SKYEYE_INFO ("SKYEYE: use xscale mmu ops\n"); 55 // NOTICE_LOG(ARM11, "SKYEYE: use xscale mmu ops\n");
56 state->mmu.ops = xscale_mmu_ops; 56 // state->mmu.ops = xscale_mmu_ops;
57 break; 57 // break;
58 case 0x41807200: //arm720t 58 //case 0x41807200: //arm720t
59 case 0x41007700: //arm7tdmi 59 //case 0x41007700: //arm7tdmi
60 case 0x41007100: //arm7100 60 //case 0x41007100: //arm7100
61 SKYEYE_INFO ( "SKYEYE: use arm7100 mmu ops\n"); 61 // NOTICE_LOG(ARM11, "SKYEYE: use arm7100 mmu ops\n");
62 state->mmu.ops = arm7100_mmu_ops; 62 // state->mmu.ops = arm7100_mmu_ops;
63 break; 63 // break;
64 case 0x41009200: 64 //case 0x41009200:
65 SKYEYE_INFO ("SKYEYE: use arm920t mmu ops\n"); 65 // NOTICE_LOG(ARM11, "SKYEYE: use arm920t mmu ops\n");
66 state->mmu.ops = arm920t_mmu_ops; 66 // state->mmu.ops = arm920t_mmu_ops;
67 break; 67 // break;
68 case 0x41069260: 68 //case 0x41069260:
69 SKYEYE_INFO ("SKYEYE: use arm926ejs mmu ops\n"); 69 // NOTICE_LOG(ARM11, "SKYEYE: use arm926ejs mmu ops\n");
70 state->mmu.ops = arm926ejs_mmu_ops; 70 // state->mmu.ops = arm926ejs_mmu_ops;
71 break; 71 // break;
72 /* case 0x560f5810: */ 72 /* case 0x560f5810: */
73 case 0x0007b000: 73 case 0x0007b000:
74 SKYEYE_INFO ("SKYEYE: use arm11jzf-s mmu ops\n"); 74 NOTICE_LOG(ARM11, "SKYEYE: use arm11jzf-s mmu ops\n");
75 state->mmu.ops = arm1176jzf_s_mmu_ops; 75 //state->mmu.ops = arm1176jzf_s_mmu_ops;
76 _dbg_assert_msg_(ARM11, false, "ImplementMe: arm1176jzf_s_mmu_ops!");
76 break; 77 break;
77 78
78 case 0xc090:
79 SKYEYE_INFO ("SKYEYE: use cortex_a9 mmu ops\n");
80 state->mmu.ops = cortex_a9_mmu_ops;
81 break;
82 default: 79 default:
83 fprintf (stderr, 80 ERROR_LOG (ARM11,
84 "SKYEYE: armmmu.c : mmu_init: unknown cpu_val&cpu_mask 0x%x\n", 81 "SKYEYE: armmmu.c : mmu_init: unknown cpu_val&cpu_mask 0x%x\n",
85 state->cpu->cpu_val & state->cpu->cpu_mask); 82 state->cpu->cpu_val & state->cpu->cpu_mask);
86 skyeye_exit (-1);
87 break; 83 break;
88 84
89 }; 85 };
90 ret = state->mmu.ops.init (state); 86 ret = state->mmu.ops.init (state);
91 state->mmu_inited = (ret == 0); 87 state->mmu_inited = (ret == 0);
92 /* initialize mmu_read and mmu_write for disassemble */ 88 /* initialize mmu_read and mmu_write for disassemble */
93 skyeye_config_t *config = get_current_config(); 89 //skyeye_config_t *config = get_current_config();
94 generic_arch_t *arch_instance = get_arch_instance(config->arch->arch_name); 90 //generic_arch_t *arch_instance = get_arch_instance(config->arch->arch_name);
95 arch_instance->mmu_read = arm_mmu_read; 91 //arch_instance->mmu_read = arm_mmu_read;
96 arch_instance->mmu_write = arm_mmu_write; 92 //arch_instance->mmu_write = arm_mmu_write;
97 93
98 return ret; 94 return ret;
99} 95}
@@ -201,41 +197,43 @@ mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr)
201 return (MMU_OPS.v2p_dbct (state, virt_addr, phys_addr)); 197 return (MMU_OPS.v2p_dbct (state, virt_addr, phys_addr));
202} 198}
203 199
204/* dis_mmu_read for disassemble */ 200//
205exception_t arm_mmu_read(short size, generic_address_t addr, uint32_t * value) 201//
206{ 202///* dis_mmu_read for disassemble */
207 ARMul_State *state; 203//exception_t arm_mmu_read(short size, uint32_t addr, uint32_t * value)
208 ARM_CPU_State *cpu = get_current_cpu(); 204//{
209 state = &cpu->core[0]; 205// ARMul_State *state;
210 switch(size){ 206// ARM_CPU_State *cpu = get_current_cpu();
211 case 8: 207// state = &cpu->core[0];
212 MMU_OPS.read_byte (state, addr, value); 208// switch(size){
213 break; 209// case 8:
214 case 16: 210// MMU_OPS.read_byte (state, addr, value);
215 case 32: 211// break;
216 break; 212// case 16:
217 default: 213// case 32:
218 printf("In %s error size %d Line %d\n", __func__, size, __LINE__); 214// break;
219 break; 215// default:
220 } 216// ERROR_LOG(ARM11, "Error size %d", size);
221 return No_exp; 217// break;
222} 218// }
223/* dis_mmu_write for disassemble */ 219// return No_exp;
224exception_t arm_mmu_write(short size, generic_address_t addr, uint32_t *value) 220//}
225{ 221///* dis_mmu_write for disassemble */
226 ARMul_State *state; 222//exception_t arm_mmu_write(short size, uint32_t addr, uint32_t *value)
227 ARM_CPU_State *cpu = get_current_cpu(); 223//{
228 state = &cpu->core[0]; 224// ARMul_State *state;
229 switch(size){ 225// ARM_CPU_State *cpu = get_current_cpu();
230 case 8: 226// state = &cpu->core[0];
231 MMU_OPS.write_byte (state, addr, value); 227// switch(size){
232 break; 228// case 8:
233 case 16: 229// MMU_OPS.write_byte (state, addr, value);
234 case 32: 230// break;
235 break; 231// case 16:
236 default: 232// case 32:
237 printf("In %s error size %d Line %d\n", __func__, size, __LINE__); 233// break;
238 break; 234// default:
239 } 235// printf("In %s error size %d Line %d\n", __func__, size, __LINE__);
240 return No_exp; 236// break;
241} 237// }
238// return No_exp;
239//}
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 @@
1/* armos.c -- ARMulator OS interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18/* This file contains a model of Demon, ARM Ltd's Debug Monitor,
19including all the SWI's required to support the C library. The code in
20it is not really for the faint-hearted (especially the abort handling
21code), but it is a complete example. Defining NOOS will disable all the
22fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI
230x11 to halt the emulator. */
24
25//chy 2005-09-12 disable below line
26//#include "config.h"
27
28#include <time.h>
29#include <errno.h>
30#include <string.h>
31#include "skyeye_defs.h"
32#ifndef __USE_LARGEFILE64
33#define __USE_LARGEFILE64 /* When use 64 bit large file need define it! for stat64*/
34#endif
35#include <fcntl.h>
36#include <sys/stat.h>
37
38
39#ifndef O_RDONLY
40#define O_RDONLY 0
41#endif
42#ifndef O_WRONLY
43#define O_WRONLY 1
44#endif
45#ifndef O_RDWR
46#define O_RDWR 2
47#endif
48#ifndef O_BINARY
49#define O_BINARY 0
50#endif
51
52#ifdef __STDC__
53#define unlink(s) remove(s)
54#endif
55
56#ifdef HAVE_UNISTD_H
57#include <unistd.h> /* For SEEK_SET etc */
58#endif
59
60#ifdef __riscos
61extern int _fisatty (FILE *);
62#define isatty_(f) _fisatty(f)
63#else
64#ifdef __ZTC__
65#include <io.h>
66#define isatty_(f) isatty((f)->_file)
67#else
68#ifdef macintosh
69#include <ioctl.h>
70#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
71#else
72#define isatty_(f) isatty (fileno (f))
73#endif
74#endif
75#endif
76
77#include "armdefs.h"
78#include "armos.h"
79#include "armemu.h"
80
81#ifndef NOOS
82#ifndef VALIDATE
83/* #ifndef ASIM */
84//chy 2005-09-12 disable below line
85//#include "armfpe.h"
86/* #endif */
87#endif
88#endif
89
90#define DUMP_SYSCALL 0
91#define dump(...) do { if (DUMP_SYSCALL) printf(__VA_ARGS__); } while(0)
92//#define debug(...) printf(__VA_ARGS__);
93#define debug(...) ;
94
95extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
96
97#ifndef FOPEN_MAX
98#define FOPEN_MAX 64
99#endif
100
101/***************************************************************************\
102* OS private Information *
103\***************************************************************************/
104
105unsigned arm_dyncom_SWI(ARMul_State * state, ARMword number)
106{
107 return ARMul_OSHandleSWI(state, number);
108}
109
110//mmap_area_t *mmap_global = NULL;
111
112static int translate_open_mode[] = {
113 O_RDONLY, /* "r" */
114 O_RDONLY + O_BINARY, /* "rb" */
115 O_RDWR, /* "r+" */
116 O_RDWR + O_BINARY, /* "r+b" */
117 O_WRONLY + O_CREAT + O_TRUNC, /* "w" */
118 O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */
119 O_RDWR + O_CREAT + O_TRUNC, /* "w+" */
120 O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */
121 O_WRONLY + O_APPEND + O_CREAT, /* "a" */
122 O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */
123 O_RDWR + O_APPEND + O_CREAT, /* "a+" */
124 O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */
125};
126//
127//static void
128//SWIWrite0 (ARMul_State * state, ARMword addr)
129//{
130// ARMword temp;
131//
132// //while ((temp = ARMul_ReadByte (state, addr++)) != 0)
133// while(1){
134// mem_read(8, addr++, &temp);
135// if(temp != 0)
136// (void) fputc ((char) temp, stdout);
137// else
138// break;
139// }
140//}
141//
142//static void
143//WriteCommandLineTo (ARMul_State * state, ARMword addr)
144//{
145// ARMword temp;
146// char *cptr = state->CommandLine;
147// if (cptr == NULL)
148// cptr = "\0";
149// do {
150// temp = (ARMword) * cptr++;
151// //ARMul_WriteByte (state, addr++, temp);
152// mem_write(8, addr++, temp);
153// }
154// while (temp != 0);
155//}
156//
157//static void
158//SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
159//{
160// char dummy[2000];
161// int flags;
162// int i;
163//
164// for (i = 0; (dummy[i] = ARMul_ReadByte (state, name + i)); i++);
165// assert(SWIflags< (sizeof(translate_open_mode)/ sizeof(translate_open_mode[0])));
166// /* Now we need to decode the Demon open mode */
167// flags = translate_open_mode[SWIflags];
168// flags = SWIflags;
169//
170// /* Filename ":tt" is special: it denotes stdin/out */
171// if (strcmp (dummy, ":tt") == 0) {
172// if (flags == O_RDONLY) /* opening tty "r" */
173// state->Reg[0] = 0; /* stdin */
174// else
175// state->Reg[0] = 1; /* stdout */
176// }
177// else {
178// state->Reg[0] = (int) open (dummy, flags, 0666);
179// }
180//}
181//
182//static void
183//SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
184//{
185// int res;
186// int i;
187// char *local = (char*) malloc (len);
188//
189// if (local == NULL) {
190// fprintf (stderr,
191// "sim: Unable to read 0x%ulx bytes - out of memory\n",
192// len);
193// return;
194// }
195//
196// res = read (f, local, len);
197// if (res > 0)
198// for (i = 0; i < res; i++)
199// //ARMul_WriteByte (state, ptr + i, local[i]);
200// mem_write(8, ptr + i, local[i]);
201// free (local);
202// //state->Reg[0] = res == -1 ? -1 : len - res;
203// state->Reg[0] = res;
204//}
205//
206//static void
207//SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
208//{
209// int res;
210// ARMword i;
211// char *local = malloc (len);
212//
213// if (local == NULL) {
214// fprintf (stderr,
215// "sim: Unable to write 0x%lx bytes - out of memory\n",
216// (long unsigned int) len);
217// return;
218// }
219//
220// for (i = 0; i < len; i++){
221// //local[i] = ARMul_ReadByte (state, ptr + i);
222// ARMword data;
223// mem_read(8, ptr + i, &data);
224// local[i] = data & 0xFF;
225// }
226//
227// res = write (f, local, len);
228// //state->Reg[0] = res == -1 ? -1 : len - res;
229// state->Reg[0] = res;
230// free (local);
231//}
232
233//static void
234//SWIflen (ARMul_State * state, ARMword fh)
235//{
236// ARMword addr;
237//
238// if (fh == 0 || fh > FOPEN_MAX) {
239// state->Reg[0] = -1L;
240// return;
241// }
242//
243// addr = lseek (fh, 0, SEEK_CUR);
244//
245// state->Reg[0] = lseek (fh, 0L, SEEK_END);
246// (void) lseek (fh, addr, SEEK_SET);
247//
248//}
249
250/***************************************************************************\
251* The emulator calls this routine when a SWI instruction is encuntered. The *
252* parameter passed is the SWI number (lower 24 bits of the instruction). *
253\***************************************************************************/
254/* ahe-ykl information is retrieved from elf header and the starting value of
255 brk_static is in sky_info_t */
256
257/* brk static hold the value of brk */
258static uint32_t brk_static = -1;
259
260unsigned
261ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
262{
263 number &= 0xfffff;
264 ARMword addr, temp;
265
266 switch (number) {
267// case SWI_Syscall:
268// if (state->Reg[7] != 0)
269// return ARMul_OSHandleSWI(state, state->Reg[7]);
270// else
271// return FALSE;
272// case SWI_Read:
273// SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
274// return TRUE;
275//
276// case SWI_GetUID32:
277// state->Reg[0] = getuid();
278// return TRUE;
279//
280// case SWI_GetGID32:
281// state->Reg[0] = getgid();
282// return TRUE;
283//
284// case SWI_GetEUID32:
285// state->Reg[0] = geteuid();
286// return TRUE;
287//
288// case SWI_GetEGID32:
289// state->Reg[0] = getegid();
290// return TRUE;
291//
292// case SWI_Write:
293// SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
294// return TRUE;
295//
296// case SWI_Open:
297// SWIopen (state, state->Reg[0], state->Reg[1]);
298// return TRUE;
299//
300// case SWI_Close:
301// state->Reg[0] = close (state->Reg[0]);
302// return TRUE;
303//
304// case SWI_Seek:{
305// /* We must return non-zero for failure */
306// state->Reg[0] =
307// lseek (state->Reg[0], state->Reg[1],
308// SEEK_SET);
309// return TRUE;
310// }
311//
312// case SWI_ExitGroup:
313// case SWI_Exit:
314// {
315// struct timeval tv;
316// //gettimeofday(&tv,NULL);
317// //printf("In %s, %d sec, %d usec\n", __FUNCTION__, tv.tv_sec, tv.tv_usec);
318// printf("passed %d sec, %lld usec\n", get_clock_sec(), get_clock_us());
319//
320// /* quit here */
321// run_command("quit");
322// return TRUE;
323// }
324// case SWI_Times:{
325// uint32_t dest = state->Reg[0];
326// struct tms now;
327// struct target_tms32 nowret;
328//
329// uint32_t ret = times(&now);
330//
331// if (ret == -1){
332// debug("syscall %s error %d\n", "SWI_Times", ret);
333// state->Reg[0] = ret;
334// return FALSE;
335// }
336//
337// nowret.tms_cstime = now.tms_cstime;
338// nowret.tms_cutime = now.tms_cutime;
339// nowret.tms_stime = now.tms_stime;
340// nowret.tms_utime = now.tms_utime;
341//
342// uint32_t offset;
343// for (offset = 0; offset < sizeof(nowret); offset++) {
344// bus_write(8, dest + offset, *((uint8_t *) &nowret + offset));
345// }
346//
347// state->Reg[0] = ret;
348// return TRUE;
349// }
350//
351// case SWI_Gettimeofday: {
352// uint32_t dest1 = state->Reg[0];
353// uint32_t dest2 = state->Reg[1]; // Unsure of this
354// struct timeval val;
355// struct timezone zone;
356// struct target_timeval32 valret;
357// struct target_timezone32 zoneret;
358//
359// uint32_t ret = gettimeofday(&val, &zone);
360// valret.tv_sec = val.tv_sec;
361// valret.tv_usec = val.tv_usec;
362// zoneret.tz_dsttime = zoneret.tz_dsttime;
363// zoneret.tz_minuteswest = zoneret.tz_minuteswest;
364//
365// if (ret == -1){
366// debug("syscall %s error %d\n", "SWI_Gettimeofday", ret);
367// state->Reg[0] = ret;
368// return FALSE;
369// }
370//
371// uint32_t offset;
372// if (dest1) {
373// for (offset = 0; offset < sizeof(valret); offset++) {
374// bus_write(8, dest1 + offset, *((uint8_t *) &valret + offset));
375// }
376// state->Reg[0] = ret;
377// }
378// if (dest2) {
379// for (offset = 0; offset < sizeof(zoneret); offset++) {
380// bus_write(8, dest2 + offset, *((uint8_t *) &zoneret + offset));
381// }
382// state->Reg[0] = ret;
383// }
384//
385// return TRUE;
386// }
387// case SWI_Brk:
388// /* initialize brk value */
389// /* suppose that brk_static doesn't reach 0xffffffff... */
390// if (brk_static == -1) {
391// brk_static = (get_skyeye_pref()->info).brk;
392// }
393//
394// /* FIXME there might be a need to do a mmap */
395//
396// if(state->Reg[0]){
397// if (get_skyeye_exec_info()->mmap_access) {
398// /* if new brk is greater than current brk, allocate memory */
399// if (state->Reg[0] > brk_static) {
400// uint32_t ret = mmap( (void *) brk_static, state->Reg[0] - brk_static,
401// PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0 );
402// if (ret != MAP_FAILED)
403// brk_static = ret;
404// }
405// }
406// brk_static = state->Reg[0];
407// //state->Reg[0] = 0; /* FIXME return value of brk set to be the address on success */
408// } else {
409// state->Reg[0] = brk_static;
410// }
411// return TRUE;
412//
413// case SWI_Break:
414// state->Emulate = FALSE;
415// return TRUE;
416//
417// case SWI_Mmap:{
418// int addr = state->Reg[0];
419// int len = state->Reg[1];
420// int prot = state->Reg[2];
421// int flag = state->Reg[3];
422// int fd = state->Reg[4];
423// int offset = state->Reg[5];
424// mmap_area_t *area = new_mmap_area(addr, len);
425// state->Reg[0] = area->bank.addr;
426// //printf("syscall %d mmap(0x%x,%x,0x%x,0x%x,%d,0x%x) = 0x%x\n",\
427// SWI_Mmap, addr, len, prot, flag, fd, offset, state->Reg[0]);
428// return TRUE;
429// }
430//
431// case SWI_Munmap:
432// state->Reg[0] = 0;
433// return TRUE;
434//
435// case SWI_Mmap2:{
436// int addr = state->Reg[0];
437// int len = state->Reg[1];
438// int prot = state->Reg[2];
439// int flag = state->Reg[3];
440// int fd = state->Reg[4];
441// int offset = state->Reg[5] * 4096; /* page offset */
442// mmap_area_t *area = new_mmap_area(addr, len);
443// state->Reg[0] = area->bank.addr;
444//
445// return TRUE;
446// }
447//
448// case SWI_Breakpoint:
449// //chy 2005-09-12 change below line
450// //state->EndCondition = RDIError_BreakpointReached;
451// //printf ("SKYEYE: in armos.c : should not come here!!!!\n");
452// state->EndCondition = 0;
453// /*modified by ksh to support breakpoiont*/
454// state->Emulate = STOP;
455// return (TRUE);
456// case SWI_Uname:
457// {
458// struct utsname *uts = (uintptr_t) state->Reg[0]; /* uname should write data in this address */
459// struct utsname utsbuf;
460// //printf("Uname size is %x\n", sizeof(utsbuf));
461// char *buf;
462// uintptr_t sp ; /* used as a temporary address */
463//
464//#define COPY_UTS_STRING(addr) \
465// buf = addr; \
466// while(*buf != NULL) { \
467// bus_write(8, sp, *buf); \
468// sp++; \
469// buf++; \
470// }
471//#define COPY_UTS(field) /*printf("%s: %s at %p\n", #field, utsbuf.field, uts->field);*/ \
472// sp = (uintptr_t) uts->field; \
473// COPY_UTS_STRING((&utsbuf)->field);
474//
475// if (uname(&utsbuf) < 0) {
476// printf("syscall uname: utsname error\n");
477// state->Reg[0] = -1;
478// return FALSE;
479// }
480//
481// /* FIXME for now, this is just the host system call
482// Some data should be missing, as it depends on
483// the version of utsname */
484// COPY_UTS(sysname);
485// COPY_UTS(nodename);
486// COPY_UTS(release);
487// COPY_UTS(version);
488// COPY_UTS(machine);
489//
490// state->Reg[0] = 0;
491// return TRUE;
492// }
493// case SWI_Fcntl:
494// {
495// uint32_t fd = state->Reg[0];
496// uint32_t cmd = state->Reg[1];
497// uint32_t arg = state->Reg[2];
498// uint32_t ret;
499//
500// switch(cmd){
501// case (F_GETFD):
502// {
503// ret = fcntl(fd, cmd, arg);
504// //printf("syscall fcntl for getfd not implemented, ret %d\n", ret);
505// state->Reg[0] = ret;
506// return FALSE;
507// }
508// default:
509// break;
510// }
511//
512// printf("syscall fcntl unimplemented fd %x cmd %x\n", fd, cmd);
513// state->Reg[0] = -1;
514// return FALSE;
515//
516// }
517// case SWI_Fstat64:
518// {
519// uint32_t dest = state->Reg[1];
520// uint32_t fd = state->Reg[0];
521// struct stat64 statbuf;
522// struct target_stat64 statret;
523// memset(&statret, 0, sizeof(struct target_stat64));
524// uint32_t ret = fstat64(fd, &statbuf);
525//
526// if (ret == -1){
527// printf("syscall %s returned error\n", "SWI_Fstat");
528// state->Reg[0] = ret;
529// return FALSE;
530// }
531//
532// /* copy statbuf to the process memory space
533// FIXME can't say if endian has an effect here */
534// uint32_t offset;
535// //printf("Fstat system is size %x\n", sizeof(statbuf));
536// //printf("Fstat target is size %x\n", sizeof(statret));
537//
538// /* we copy system structure data stat64 into arm fixed size structure target_stat64 */
539// statret.st_dev = statbuf.st_dev;
540// statret.st_ino = statbuf.st_ino;
541// statret.st_mode = statbuf.st_mode;
542// statret.st_nlink = statbuf.st_nlink;
543// statret.st_uid = statbuf.st_uid;
544// statret.st_gid = statbuf.st_gid;
545// statret.st_rdev = statbuf.st_rdev;
546// statret.st_size = statbuf.st_size;
547// statret.st_blksize = statbuf.st_blksize;
548// statret.st_blocks = statbuf.st_blocks;
549// statret.st32_atime = statbuf.st_atime;
550// statret.st32_mtime = statbuf.st_mtime;
551// statret.st32_ctime = statbuf.st_ctime;
552//
553// for (offset = 0; offset < sizeof(statret); offset++) {
554// bus_write(8, dest + offset, *((uint8_t *) &statret + offset));
555// }
556//
557// state->Reg[0] = ret;
558// return TRUE;
559// }
560// case SWI_Set_tls:
561// {
562// //printf("syscall set_tls unimplemented\n");
563// state->mmu.thread_uro_id = state->Reg[0];
564// state->CP15[CP15_THREAD_URO - CP15_BASE] = state->Reg[0];
565// state->Reg[0] = 0;
566// return FALSE;
567// }
568//#if 0
569// case SWI_Clock:
570// /* return number of centi-seconds... */
571// state->Reg[0] =
572//#ifdef CLOCKS_PER_SEC
573// (CLOCKS_PER_SEC >= 100)
574// ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
575// : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
576//#else
577// /* presume unix... clock() returns microseconds */
578// (ARMword) (clock () / 10000);
579//#endif
580// return (TRUE);
581//
582// case SWI_Time:
583// state->Reg[0] = (ARMword) time (NULL);
584// return (TRUE);
585// case SWI_Flen:
586// SWIflen (state, state->Reg[0]);
587// return (TRUE);
588//
589//#endif
590 default:
591
592 _dbg_assert_msg_(ARM11, false, "ImplementMe: ARMul_OSHandleSWI!");
593
594 return (FALSE);
595 }
596}
597//
598///**
599// * @brief For mmap syscall.A mmap_area is a memory bank. Get from ppc.
600// */
601//static mmap_area_t* new_mmap_area(int sim_addr, int len){
602// mmap_area_t *area = (mmap_area_t *)malloc(sizeof(mmap_area_t));
603// if(area == NULL){
604// printf("error, failed %s\n",__FUNCTION__);
605// exit(0);
606// }
607//#if FAST_MEMORY
608// if (mmap_next_base == -1)
609// {
610// mmap_next_base = get_skyeye_exec_info()->brk;
611// }
612//#endif
613//
614// memset(area, 0x0, sizeof(mmap_area_t));
615// area->bank.addr = mmap_next_base;
616// area->bank.len = len;
617// area->bank.bank_write = mmap_mem_write;
618// area->bank.bank_read = mmap_mem_read;
619// area->bank.type = MEMTYPE_RAM;
620// area->bank.objname = "mmap";
621// addr_mapping(&area->bank);
622//
623//#if FAST_MEMORY
624// if (get_skyeye_exec_info()->mmap_access)
625// {
626// /* FIXME check proper flags */
627// /* FIXME we may delete the need of banks up there */
628// uint32_t ret = mmap(mmap_next_base, len, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
629// mmap_next_base = ret;
630// }
631// area->mmap_addr = (uint8_t*)get_dma_addr(mmap_next_base);
632//#else
633// area->mmap_addr = malloc(len);
634// if(area->mmap_addr == NULL){
635// printf("error mmap malloc\n");
636// exit(0);
637// }
638// memset(area->mmap_addr, 0x0, len);
639//#endif
640//
641// area->next = NULL;
642// if(mmap_global){
643// area->next = mmap_global->next;
644// mmap_global->next = area;
645// }else{
646// mmap_global = area;
647// }
648// mmap_next_base = mmap_next_base + len;
649// return area;
650//}
651//
652//static mmap_area_t *get_mmap_area(int addr){
653// mmap_area_t *tmp = mmap_global;
654// while(tmp){
655// if ((tmp->bank.addr <= addr) && (tmp->bank.addr + tmp->bank.len > addr)){
656// return tmp;
657// }
658// tmp = tmp->next;
659// }
660// printf("cannot get mmap area:addr=0x%x\n", addr);
661// return NULL;
662//}
663//
664///**
665// * @brief the mmap_area bank write function. Get from ppc.
666// *
667// * @param size size to write, 8/16/32
668// * @param addr address to write
669// * @param value value to write
670// *
671// * @return sucess return 1,otherwise 0.
672// */
673//static char mmap_mem_write(short size, int addr, uint32_t value){
674// mmap_area_t *area_tmp = get_mmap_area(addr);
675// mem_bank_t *bank_tmp = &area_tmp->bank;
676// int offset = addr - bank_tmp->addr;
677// switch(size){
678// case 8:{
679// //uint8_t value_endian = value;
680// uint8_t value_endian = (uint8_t)value;
681// *(uint8_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
682// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
683// break;
684// }
685// case 16:{
686// //uint16_t value_endian = half_to_BE((uint16_t)value);
687// uint16_t value_endian = ((uint16_t)value);
688// *(uint16_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
689// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
690// break;
691// }
692// case 32:{
693// //uint32_t value_endian = word_to_BE((uint32_t)value);
694// uint32_t value_endian = ((uint32_t)value);
695// *(uint32_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
696// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
697// break;
698// }
699// default:
700// printf("invalid size %d\n",size);
701// return 0;
702// }
703// return 1;
704//}
705//
706///**
707// * @brief the mmap_area bank read function. Get from ppc.
708// *
709// * @param size size to read, 8/16/32
710// * @param addr address to read
711// * @param value value to read
712// *
713// * @return sucess return 1,otherwise 0.
714// */
715//static char mmap_mem_read(short size, int addr, uint32_t * value){
716// mmap_area_t *area_tmp = get_mmap_area(addr);
717// mem_bank_t *bank_tmp = &area_tmp->bank;
718// int offset = addr - bank_tmp->addr;
719// switch(size){
720// case 8:{
721// //*(uint8_t *)value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
722// *value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
723// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
724// break;
725// }
726// case 16:{
727// //*(uint16_t *)value = half_from_BE(*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
728// *value = (*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
729// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint16_t*)value);
730// break;
731// }
732// case 32:
733// //*value = (uint32_t)word_from_BE(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
734// *value = (uint32_t)(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
735// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
736// break;
737// default:
738// printf("invalid size %d\n",size);
739// return 0;
740// }
741// return 1;
742//}
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 @@
1/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#include "armdefs.h"
19#include "armemu.h"
20//#include "ansidecl.h"
21#include "skyeye_defs.h"
22unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
23 unsigned cpnum);
24//extern int skyeye_instr_debug;
25/* Definitions for the support routines. */
26
27static ARMword ModeToBank (ARMword);
28static void EnvokeList (ARMul_State *, unsigned int, unsigned int);
29
30struct EventNode
31{ /* An event list node. */
32 unsigned (*func) (ARMul_State *); /* The function to call. */
33 struct EventNode *next;
34};
35
36/* This routine returns the value of a register from a mode. */
37
38ARMword
39ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
40{
41 mode &= MODEBITS;
42 if (mode != state->Mode)
43 return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
44 else
45 return (state->Reg[reg]);
46}
47
48/* This routine sets the value of a register for a mode. */
49
50void
51ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
52{
53 mode &= MODEBITS;
54 if (mode != state->Mode)
55 state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
56 else
57 state->Reg[reg] = value;
58}
59
60/* This routine returns the value of the PC, mode independently. */
61
62ARMword
63ARMul_GetPC (ARMul_State * state)
64{
65 if (state->Mode > SVC26MODE)
66 return state->Reg[15];
67 else
68 return R15PC;
69}
70
71/* This routine returns the value of the PC, mode independently. */
72
73ARMword
74ARMul_GetNextPC (ARMul_State * state)
75{
76 if (state->Mode > SVC26MODE)
77 return state->Reg[15] + isize;
78 else
79 return (state->Reg[15] + isize) & R15PCBITS;
80}
81
82/* This routine sets the value of the PC. */
83
84void
85ARMul_SetPC (ARMul_State * state, ARMword value)
86{
87 if (ARMul_MODE32BIT)
88 state->Reg[15] = value & PCBITS;
89 else
90 state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
91 FLUSHPIPE;
92}
93
94/* This routine returns the value of register 15, mode independently. */
95
96ARMword
97ARMul_GetR15 (ARMul_State * state)
98{
99 if (state->Mode > SVC26MODE)
100 return (state->Reg[15]);
101 else
102 return (R15PC | ECC | ER15INT | EMODE);
103}
104
105/* This routine sets the value of Register 15. */
106
107void
108ARMul_SetR15 (ARMul_State * state, ARMword value)
109{
110 if (ARMul_MODE32BIT)
111 state->Reg[15] = value & PCBITS;
112 else {
113 state->Reg[15] = value;
114 ARMul_R15Altered (state);
115 }
116 FLUSHPIPE;
117}
118
119/* This routine returns the value of the CPSR. */
120
121ARMword
122ARMul_GetCPSR (ARMul_State * state)
123{
124 //chy 2003-08-20: below is from gdb20030716, maybe isn't suitable for system simulator
125 //return (CPSR | state->Cpsr); for gdb20030716
126 return (CPSR); //had be tested in old skyeye with gdb5.0-5.3
127}
128
129/* This routine sets the value of the CPSR. */
130
131void
132ARMul_SetCPSR (ARMul_State * state, ARMword value)
133{
134 state->Cpsr = value;
135 ARMul_CPSRAltered (state);
136}
137
138/* This routine does all the nasty bits involved in a write to the CPSR,
139 including updating the register bank, given a MSR instruction. */
140
141void
142ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
143{
144 state->Cpsr = ARMul_GetCPSR (state);
145 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
146 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
147 /* In user mode, only write flags. */
148 if (BIT (16))
149 SETPSR_C (state->Cpsr, rhs);
150 if (BIT (17))
151 SETPSR_X (state->Cpsr, rhs);
152 if (BIT (18))
153 SETPSR_S (state->Cpsr, rhs);
154 }
155 if (BIT (19))
156 SETPSR_F (state->Cpsr, rhs);
157 ARMul_CPSRAltered (state);
158}
159
160/* Get an SPSR from the specified mode. */
161
162ARMword
163ARMul_GetSPSR (ARMul_State * state, ARMword mode)
164{
165 ARMword bank = ModeToBank (mode & MODEBITS);
166
167 if (!BANK_CAN_ACCESS_SPSR (bank))
168 return ARMul_GetCPSR (state);
169
170 return state->Spsr[bank];
171}
172
173/* This routine does a write to an SPSR. */
174
175void
176ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
177{
178 ARMword bank = ModeToBank (mode & MODEBITS);
179
180 if (BANK_CAN_ACCESS_SPSR (bank))
181 state->Spsr[bank] = value;
182}
183
184/* This routine does a write to the current SPSR, given an MSR instruction. */
185
186void
187ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
188{
189 if (BANK_CAN_ACCESS_SPSR (state->Bank)) {
190 if (BIT (16))
191 SETPSR_C (state->Spsr[state->Bank], rhs);
192 if (BIT (17))
193 SETPSR_X (state->Spsr[state->Bank], rhs);
194 if (BIT (18))
195 SETPSR_S (state->Spsr[state->Bank], rhs);
196 if (BIT (19))
197 SETPSR_F (state->Spsr[state->Bank], rhs);
198 }
199}
200
201/* This routine updates the state of the emulator after the Cpsr has been
202 changed. Both the processor flags and register bank are updated. */
203
204void
205ARMul_CPSRAltered (ARMul_State * state)
206{
207 ARMword oldmode;
208
209 if (state->prog32Sig == LOW)
210 state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
211
212 oldmode = state->Mode;
213
214 if (state->Mode != (state->Cpsr & MODEBITS)) {
215 state->Mode =
216 ARMul_SwitchMode (state, state->Mode,
217 state->Cpsr & MODEBITS);
218
219 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
220 }
221 //state->Cpsr &= ~MODEBITS;
222
223 ASSIGNINT (state->Cpsr & INTBITS);
224 //state->Cpsr &= ~INTBITS;
225 ASSIGNN ((state->Cpsr & NBIT) != 0);
226 //state->Cpsr &= ~NBIT;
227 ASSIGNZ ((state->Cpsr & ZBIT) != 0);
228 //state->Cpsr &= ~ZBIT;
229 ASSIGNC ((state->Cpsr & CBIT) != 0);
230 //state->Cpsr &= ~CBIT;
231 ASSIGNV ((state->Cpsr & VBIT) != 0);
232 //state->Cpsr &= ~VBIT;
233 ASSIGNS ((state->Cpsr & SBIT) != 0);
234 //state->Cpsr &= ~SBIT;
235#ifdef MODET
236 ASSIGNT ((state->Cpsr & TBIT) != 0);
237 //state->Cpsr &= ~TBIT;
238#endif
239
240 if (oldmode > SVC26MODE) {
241 if (state->Mode <= SVC26MODE) {
242 state->Emulate = CHANGEMODE;
243 state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
244 }
245 }
246 else {
247 if (state->Mode > SVC26MODE) {
248 state->Emulate = CHANGEMODE;
249 state->Reg[15] = R15PC;
250 }
251 else
252 state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
253 }
254}
255
256/* This routine updates the state of the emulator after register 15 has
257 been changed. Both the processor flags and register bank are updated.
258 This routine should only be called from a 26 bit mode. */
259
260void
261ARMul_R15Altered (ARMul_State * state)
262{
263 if (state->Mode != R15MODE) {
264 state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
265 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
266 }
267
268 if (state->Mode > SVC26MODE)
269 state->Emulate = CHANGEMODE;
270
271 ASSIGNR15INT (R15INT);
272
273 ASSIGNN ((state->Reg[15] & NBIT) != 0);
274 ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
275 ASSIGNC ((state->Reg[15] & CBIT) != 0);
276 ASSIGNV ((state->Reg[15] & VBIT) != 0);
277}
278
279/* This routine controls the saving and restoring of registers across mode
280 changes. The regbank matrix is largely unused, only rows 13 and 14 are
281 used across all modes, 8 to 14 are used for FIQ, all others use the USER
282 column. It's easier this way. old and new parameter are modes numbers.
283 Notice the side effect of changing the Bank variable. */
284
285ARMword
286ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
287{
288 unsigned i;
289 ARMword oldbank;
290 ARMword newbank;
291 static int revision_value = 53;
292
293 oldbank = ModeToBank (oldmode);
294 newbank = state->Bank = ModeToBank (newmode);
295
296 /* Do we really need to do it? */
297 if (oldbank != newbank) {
298 if (oldbank == 3 && newbank == 2) {
299 //printf("icounter is %d PC is %x MODE CHANGED : %d --> %d\n", state->NumInstrs, state->pc, oldbank, newbank);
300 if (state->NumInstrs >= 5832487) {
301// printf("%d, ", state->NumInstrs + revision_value);
302// printf("revision_value : %d\n", revision_value);
303 revision_value ++;
304 }
305 }
306 /* Save away the old registers. */
307 switch (oldbank) {
308 case USERBANK:
309 case IRQBANK:
310 case SVCBANK:
311 case ABORTBANK:
312 case UNDEFBANK:
313 if (newbank == FIQBANK)
314 for (i = 8; i < 13; i++)
315 state->RegBank[USERBANK][i] =
316 state->Reg[i];
317 state->RegBank[oldbank][13] = state->Reg[13];
318 state->RegBank[oldbank][14] = state->Reg[14];
319 break;
320 case FIQBANK:
321 for (i = 8; i < 15; i++)
322 state->RegBank[FIQBANK][i] = state->Reg[i];
323 break;
324 case DUMMYBANK:
325 for (i = 8; i < 15; i++)
326 state->RegBank[DUMMYBANK][i] = 0;
327 break;
328 default:
329 abort ();
330 }
331
332 /* Restore the new registers. */
333 switch (newbank) {
334 case USERBANK:
335 case IRQBANK:
336 case SVCBANK:
337 case ABORTBANK:
338 case UNDEFBANK:
339 if (oldbank == FIQBANK)
340 for (i = 8; i < 13; i++)
341 state->Reg[i] =
342 state->RegBank[USERBANK][i];
343 state->Reg[13] = state->RegBank[newbank][13];
344 state->Reg[14] = state->RegBank[newbank][14];
345 break;
346 case FIQBANK:
347 for (i = 8; i < 15; i++)
348 state->Reg[i] = state->RegBank[FIQBANK][i];
349 break;
350 case DUMMYBANK:
351 for (i = 8; i < 15; i++)
352 state->Reg[i] = 0;
353 break;
354 default:
355 abort ();
356 }
357 }
358
359 return newmode;
360}
361
362/* Given a processor mode, this routine returns the
363 register bank that will be accessed in that mode. */
364
365static ARMword
366ModeToBank (ARMword mode)
367{
368 static ARMword bankofmode[] = {
369 USERBANK, FIQBANK, IRQBANK, SVCBANK,
370 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
371 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
372 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
373 USERBANK, FIQBANK, IRQBANK, SVCBANK,
374 DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
375 DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
376 DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
377 };
378
379 if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
380 return DUMMYBANK;
381
382 return bankofmode[mode];
383}
384
385/* Returns the register number of the nth register in a reg list. */
386
387unsigned
388ARMul_NthReg (ARMword instr, unsigned number)
389{
390 unsigned bit, upto;
391
392 for (bit = 0, upto = 0; upto <= number; bit++)
393 if (BIT (bit))
394 upto++;
395
396 return (bit - 1);
397}
398
399/* Assigns the N and Z flags depending on the value of result. */
400
401void
402ARMul_NegZero (ARMul_State * state, ARMword result)
403{
404 if (NEG (result)) {
405 SETN;
406 CLEARZ;
407 }
408 else if (result == 0) {
409 CLEARN;
410 SETZ;
411 }
412 else {
413 CLEARN;
414 CLEARZ;
415 }
416}
417
418/* Compute whether an addition of A and B, giving RESULT, overflowed. */
419
420int
421AddOverflow (ARMword a, ARMword b, ARMword result)
422{
423 return ((NEG (a) && NEG (b) && POS (result))
424 || (POS (a) && POS (b) && NEG (result)));
425}
426
427/* Compute whether a subtraction of A and B, giving RESULT, overflowed. */
428
429int
430SubOverflow (ARMword a, ARMword b, ARMword result)
431{
432 return ((NEG (a) && POS (b) && POS (result))
433 || (POS (a) && NEG (b) && NEG (result)));
434}
435
436/* Assigns the C flag after an addition of a and b to give result. */
437
438void
439ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
440{
441 ASSIGNC ((NEG (a) && NEG (b)) ||
442 (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
443}
444
445/* Assigns the V flag after an addition of a and b to give result. */
446
447void
448ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
449{
450 ASSIGNV (AddOverflow (a, b, result));
451}
452
453/* Assigns the C flag after an subtraction of a and b to give result. */
454
455void
456ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
457{
458 ASSIGNC ((NEG (a) && POS (b)) ||
459 (NEG (a) && POS (result)) || (POS (b) && POS (result)));
460}
461
462/* Assigns the V flag after an subtraction of a and b to give result. */
463
464void
465ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
466{
467 ASSIGNV (SubOverflow (a, b, result));
468}
469
470/* This function does the work of generating the addresses used in an
471 LDC instruction. The code here is always post-indexed, it's up to the
472 caller to get the input address correct and to handle base register
473 modification. It also handles the Busy-Waiting. */
474
475void
476ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
477{
478 unsigned cpab;
479 ARMword data;
480
481 UNDEF_LSCPCBaseWb;
482 //printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
483/*chy 2004-05-23 should update this function in the future,should concern dataabort*/
484// chy 2004-05-25 , fix it now,so needn't printf
485// printf("SKYEYE ARMul_LDC, should update this function!!!!!\n");
486 //exit(-1);
487
488 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
489 /*
490 printf
491 ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n",
492 CPNum, instr, address);
493 */
494 ARMul_UndefInstr (state, instr);
495 return;
496 }
497
498 if (ADDREXCEPT (address))
499 INTERNALABORT (address);
500
501 cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
502 while (cpab == ARMul_BUSY) {
503 ARMul_Icycles (state, 1, 0);
504
505 if (IntPending (state)) {
506 cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT,
507 instr, 0);
508 return;
509 }
510 else
511 cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr,
512 0);
513 }
514 if (cpab == ARMul_CANT) {
515 /*
516 printf
517 ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n",
518 CPNum, instr, address);
519 */
520 CPTAKEABORT;
521 return;
522 }
523
524 cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
525 data = ARMul_LoadWordN (state, address);
526 //chy 2004-05-25
527 if (state->abortSig || state->Aborted)
528 goto L_ldc_takeabort;
529
530 BUSUSEDINCPCN;
531//chy 2004-05-25
532/*
533 if (BIT (21))
534 LSBase = state->Base;
535*/
536
537 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
538
539 while (cpab == ARMul_INC) {
540 address += 4;
541 data = ARMul_LoadWordN (state, address);
542 //chy 2004-05-25
543 if (state->abortSig || state->Aborted)
544 goto L_ldc_takeabort;
545
546 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
547 }
548
549//chy 2004-05-25
550 L_ldc_takeabort:
551 if (BIT (21)) {
552 if (!
553 ((state->abortSig || state->Aborted)
554 && state->lateabtSig == LOW))
555 LSBase = state->Base;
556 }
557
558 if (state->abortSig || state->Aborted)
559 TAKEABORT;
560}
561
562/* This function does the work of generating the addresses used in an
563 STC instruction. The code here is always post-indexed, it's up to the
564 caller to get the input address correct and to handle base register
565 modification. It also handles the Busy-Waiting. */
566
567void
568ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
569{
570 unsigned cpab;
571 ARMword data;
572
573 UNDEF_LSCPCBaseWb;
574
575 //printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
576 /*chy 2004-05-23 should update this function in the future,should concern dataabort */
577// skyeye_instr_debug=0;printf("SKYEYE debug end!!!!\n");
578// chy 2004-05-25 , fix it now,so needn't printf
579// printf("SKYEYE ARMul_STC, should update this function!!!!!\n");
580
581 //exit(-1);
582 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
583 /*
584 printf
585 ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr, CPnum is %x, instr %x, addr %x\n",
586 CPNum, instr, address);
587 */
588 ARMul_UndefInstr (state, instr);
589 return;
590 }
591
592 if (ADDREXCEPT (address) || VECTORACCESS (address))
593 INTERNALABORT (address);
594
595 cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
596 while (cpab == ARMul_BUSY) {
597 ARMul_Icycles (state, 1, 0);
598 if (IntPending (state)) {
599 cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT,
600 instr, 0);
601 return;
602 }
603 else
604 cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr,
605 &data);
606 }
607
608 if (cpab == ARMul_CANT) {
609 /*
610 printf
611 ("SKYEYE ARMul_STC,CANT, undefinstr, CPnum is %x, instr %x, addr %x\n",
612 CPNum, instr, address);
613 */
614 CPTAKEABORT;
615 return;
616 }
617#ifndef MODE32
618 if (ADDREXCEPT (address) || VECTORACCESS (address))
619 INTERNALABORT (address);
620#endif
621 BUSUSEDINCPCN;
622//chy 2004-05-25
623/*
624 if (BIT (21))
625 LSBase = state->Base;
626*/
627 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
628 ARMul_StoreWordN (state, address, data);
629 //chy 2004-05-25
630 if (state->abortSig || state->Aborted)
631 goto L_stc_takeabort;
632
633 while (cpab == ARMul_INC) {
634 address += 4;
635 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
636 ARMul_StoreWordN (state, address, data);
637 //chy 2004-05-25
638 if (state->abortSig || state->Aborted)
639 goto L_stc_takeabort;
640 }
641//chy 2004-05-25
642 L_stc_takeabort:
643 if (BIT (21)) {
644 if (!
645 ((state->abortSig || state->Aborted)
646 && state->lateabtSig == LOW))
647 LSBase = state->Base;
648 }
649
650 if (state->abortSig || state->Aborted)
651 TAKEABORT;
652}
653
654/* This function does the Busy-Waiting for an MCR instruction. */
655
656void
657ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
658{
659 unsigned cpab;
660
661 //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source);
662 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
663 //chy 2004-07-19 should fix in the future ????!!!!
664 //printf("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source);
665 ARMul_UndefInstr (state, instr);
666 return;
667 }
668
669 cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
670
671 while (cpab == ARMul_BUSY) {
672 ARMul_Icycles (state, 1, 0);
673
674 if (IntPending (state)) {
675 cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT,
676 instr, 0);
677 return;
678 }
679 else
680 cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr,
681 source);
682 }
683
684 if (cpab == ARMul_CANT) {
685 printf ("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source);
686 ARMul_Abort (state, ARMul_UndefinedInstrV);
687 }
688 else {
689 BUSUSEDINCPCN;
690 ARMul_Ccycles (state, 1, 0);
691 }
692}
693
694/* This function does the Busy-Waiting for an MCRR instruction. */
695
696void
697ARMul_MCRR (ARMul_State * state, ARMword instr, ARMword source1, ARMword source2)
698{
699 unsigned cpab;
700
701 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
702 ARMul_UndefInstr (state, instr);
703 return;
704 }
705
706 cpab = (state->MCRR[CPNum]) (state, ARMul_FIRST, instr, source1, source2);
707
708 while (cpab == ARMul_BUSY) {
709 ARMul_Icycles (state, 1, 0);
710
711 if (IntPending (state)) {
712 cpab = (state->MCRR[CPNum]) (state, ARMul_INTERRUPT,
713 instr, 0, 0);
714 return;
715 }
716 else
717 cpab = (state->MCRR[CPNum]) (state, ARMul_BUSY, instr,
718 source1, source2);
719 }
720 if (cpab == ARMul_CANT) {
721 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x, source %x %x\n", __FUNCTION__, CPNum, instr, source1, source2);
722 ARMul_Abort (state, ARMul_UndefinedInstrV);
723 }
724 else {
725 BUSUSEDINCPCN;
726 ARMul_Ccycles (state, 1, 0);
727 }
728}
729
730/* This function does the Busy-Waiting for an MRC instruction. */
731
732ARMword
733ARMul_MRC (ARMul_State * state, ARMword instr)
734{
735 unsigned cpab;
736 ARMword result = 0;
737
738 //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
739 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
740 //chy 2004-07-19 should fix in the future????!!!!
741 //printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n",CPNum, instr);
742 ARMul_UndefInstr (state, instr);
743 return -1;
744 }
745
746 cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
747 while (cpab == ARMul_BUSY) {
748 ARMul_Icycles (state, 1, 0);
749 if (IntPending (state)) {
750 cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
751 instr, 0);
752 return (0);
753 }
754 else
755 cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
756 &result);
757 }
758 if (cpab == ARMul_CANT) {
759 printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr);
760 ARMul_Abort (state, ARMul_UndefinedInstrV);
761 /* Parent will destroy the flags otherwise. */
762 result = ECC;
763 }
764 else {
765 BUSUSEDINCPCN;
766 ARMul_Ccycles (state, 1, 0);
767 ARMul_Icycles (state, 1, 0);
768 }
769
770 return result;
771}
772
773/* This function does the Busy-Waiting for an MRRC instruction. (to verify) */
774
775void
776ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2)
777{
778 unsigned cpab;
779 ARMword result1 = 0;
780 ARMword result2 = 0;
781
782 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
783 ARMul_UndefInstr (state, instr);
784 return;
785 }
786
787 cpab = (state->MRRC[CPNum]) (state, ARMul_FIRST, instr, &result1, &result2);
788 while (cpab == ARMul_BUSY) {
789 ARMul_Icycles (state, 1, 0);
790 if (IntPending (state)) {
791 cpab = (state->MRRC[CPNum]) (state, ARMul_INTERRUPT,
792 instr, 0, 0);
793 return;
794 }
795 else
796 cpab = (state->MRRC[CPNum]) (state, ARMul_BUSY, instr,
797 &result1, &result2);
798 }
799 if (cpab == ARMul_CANT) {
800 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x\n", __FUNCTION__, CPNum, instr);
801 ARMul_Abort (state, ARMul_UndefinedInstrV);
802 }
803 else {
804 BUSUSEDINCPCN;
805 ARMul_Ccycles (state, 1, 0);
806 ARMul_Icycles (state, 1, 0);
807 }
808
809 *dest1 = result1;
810 *dest2 = result2;
811}
812
813/* This function does the Busy-Waiting for an CDP instruction. */
814
815void
816ARMul_CDP (ARMul_State * state, ARMword instr)
817{
818 unsigned cpab;
819
820 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
821 ARMul_UndefInstr (state, instr);
822 return;
823 }
824 cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
825 while (cpab == ARMul_BUSY) {
826 ARMul_Icycles (state, 1, 0);
827 if (IntPending (state)) {
828 cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT,
829 instr);
830 return;
831 }
832 else
833 cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
834 }
835 if (cpab == ARMul_CANT)
836 ARMul_Abort (state, ARMul_UndefinedInstrV);
837 else
838 BUSUSEDN;
839}
840
841/* This function handles Undefined instructions, as CP isntruction. */
842
843void
844ARMul_UndefInstr (ARMul_State * state, ARMword instr)
845{
846 ERROR_LOG(ARM11, "Undefined instruction!! Instr: 0x%x", instr);
847 ARMul_Abort (state, ARMul_UndefinedInstrV);
848}
849
850/* Return TRUE if an interrupt is pending, FALSE otherwise. */
851
852unsigned
853IntPending (ARMul_State * state)
854{
855 /* Any exceptions. */
856 if (state->NresetSig == LOW) {
857 ARMul_Abort (state, ARMul_ResetV);
858 return TRUE;
859 }
860 else if (!state->NfiqSig && !FFLAG) {
861 ARMul_Abort (state, ARMul_FIQV);
862 return TRUE;
863 }
864 else if (!state->NirqSig && !IFLAG) {
865 ARMul_Abort (state, ARMul_IRQV);
866 return TRUE;
867 }
868
869 return FALSE;
870}
871
872/* Align a word access to a non word boundary. */
873
874ARMword
875ARMul_Align (ARMul_State *state, ARMword address, ARMword data)
876{
877 /* This code assumes the address is really unaligned,
878 as a shift by 32 is undefined in C. */
879
880 address = (address & 3) << 3; /* Get the word address. */
881 return ((data >> address) | (data << (32 - address))); /* rot right */
882}
883
884/* This routine is used to call another routine after a certain number of
885 cycles have been executed. The first parameter is the number of cycles
886 delay before the function is called, the second argument is a pointer
887 to the function. A delay of zero doesn't work, just call the function. */
888
889void
890ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay,
891 unsigned (*what) (ARMul_State *))
892{
893 unsigned int when;
894 struct EventNode *event;
895
896 if (state->EventSet++ == 0)
897 state->Now = ARMul_Time (state);
898 when = (state->Now + delay) % EVENTLISTSIZE;
899 event = (struct EventNode *) malloc (sizeof (struct EventNode));
900
901 _dbg_assert_msg_(ARM11, event, "SKYEYE:ARMul_ScheduleEvent: malloc event error\n");
902
903 event->func = what;
904 event->next = *(state->EventPtr + when);
905 *(state->EventPtr + when) = event;
906}
907
908/* This routine is called at the beginning of
909 every cycle, to envoke scheduled events. */
910
911void
912ARMul_EnvokeEvent (ARMul_State * state)
913{
914 static unsigned int then;
915
916 then = state->Now;
917 state->Now = ARMul_Time (state) % EVENTLISTSIZE;
918 if (then < state->Now)
919 /* Schedule events. */
920 EnvokeList (state, then, state->Now);
921 else if (then > state->Now) {
922 /* Need to wrap around the list. */
923 EnvokeList (state, then, EVENTLISTSIZE - 1L);
924 EnvokeList (state, 0L, state->Now);
925 }
926}
927
928/* Envokes all the entries in a range. */
929
930static void
931EnvokeList (ARMul_State * state, unsigned int from, unsigned int to)
932{
933 for (; from <= to; from++) {
934 struct EventNode *anevent;
935
936 anevent = *(state->EventPtr + from);
937 while (anevent) {
938 (anevent->func) (state);
939 state->EventSet--;
940 anevent = anevent->next;
941 }
942 *(state->EventPtr + from) = NULL;
943 }
944}
945
946/* This routine is returns the number of clock ticks since the last reset. */
947
948unsigned int
949ARMul_Time (ARMul_State * state)
950{
951 return (state->NumScycles + state->NumNcycles +
952 state->NumIcycles + state->NumCcycles + state->NumFcycles);
953}
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 @@
1/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18/* This file contains a complete ARMulator memory model, modelling a
19"virtual memory" system. A much simpler model can be found in armfast.c,
20and that model goes faster too, but has a fixed amount of memory. This
21model's memory has 64K pages, allocated on demand from a 64K entry page
22table. The routines PutWord and GetWord implement this. Pages are never
23freed as they might be needed again. A single area of memory may be
24defined to generate aborts. */
25
26#include "armdefs.h"
27#include "skyeye_defs.h"
28//#include "code_cov.h"
29
30#ifdef VALIDATE /* for running the validate suite */
31#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
32#define ABORTS 1
33#endif
34
35/* #define ABORTS */
36
37#ifdef ABORTS /* the memory system will abort */
38/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
39 For the new test suite Abort between 8 Mbytes and 26 Mbytes */
40/* #define LOWABORT 32 * 1024
41#define HIGHABORT 32 * 1024 * 1024 */
42#define LOWABORT 8 * 1024 * 1024
43#define HIGHABORT 26 * 1024 * 1024
44
45#endif
46
47#define NUMPAGES 64 * 1024
48#define PAGESIZE 64 * 1024
49#define PAGEBITS 16
50#define OFFSETBITS 0xffff
51//chy 2003-08-19: seems no use ????
52int SWI_vector_installed = FALSE;
53extern ARMword skyeye_cachetype;
54
55/***************************************************************************\
56* Get a byte into Virtual Memory, maybe allocating the page *
57\***************************************************************************/
58static fault_t
59GetByte (ARMul_State * state, ARMword address, ARMword * data)
60{
61 fault_t fault;
62
63 fault = mmu_read_byte (state, address, data);
64 if (fault) {
65//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
66// printf("SKYEYE: GetByte fault %d \n", fault);
67 }
68 return fault;
69}
70
71/***************************************************************************\
72* Get a halfword into Virtual Memory, maybe allocating the page *
73\***************************************************************************/
74static fault_t
75GetHalfWord (ARMul_State * state, ARMword address, ARMword * data)
76{
77 fault_t fault;
78
79 fault = mmu_read_halfword (state, address, data);
80 if (fault) {
81//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
82// printf("SKYEYE: GetHalfWord fault %d \n", fault);
83 }
84 return fault;
85}
86
87/***************************************************************************\
88* Get a Word from Virtual Memory, maybe allocating the page *
89\***************************************************************************/
90
91static fault_t
92GetWord (ARMul_State * state, ARMword address, ARMword * data)
93{
94 fault_t fault;
95
96 fault = mmu_read_word (state, address, data);
97 if (fault) {
98//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
99#if 0
100/* XXX */ extern int hack;
101 hack = 1;
102#endif
103#if 0
104 printf ("mmu_read_word at 0x%08x: ", address);
105 switch (fault) {
106 case ALIGNMENT_FAULT:
107 printf ("ALIGNMENT_FAULT");
108 break;
109 case SECTION_TRANSLATION_FAULT:
110 printf ("SECTION_TRANSLATION_FAULT");
111 break;
112 case PAGE_TRANSLATION_FAULT:
113 printf ("PAGE_TRANSLATION_FAULT");
114 break;
115 case SECTION_DOMAIN_FAULT:
116 printf ("SECTION_DOMAIN_FAULT");
117 break;
118 case SECTION_PERMISSION_FAULT:
119 printf ("SECTION_PERMISSION_FAULT");
120 break;
121 case SUBPAGE_PERMISSION_FAULT:
122 printf ("SUBPAGE_PERMISSION_FAULT");
123 break;
124 default:
125 printf ("Unrecognized fault number!");
126 }
127 printf ("\tpc = 0x%08x\n", state->Reg[15]);
128#endif
129 }
130 return fault;
131}
132
133//2003-07-10 chy: lyh change
134/****************************************************************************\
135 * Load a Instrion Word into Virtual Memory *
136\****************************************************************************/
137static fault_t
138LoadInstr (ARMul_State * state, ARMword address, ARMword * instr)
139{
140 fault_t fault;
141 fault = mmu_load_instr (state, address, instr);
142 return fault;
143 //if (fault)
144 // log_msg("load_instr fault = %d, address = %x\n", fault, address);
145}
146
147/***************************************************************************\
148* Put a byte into Virtual Memory, maybe allocating the page *
149\***************************************************************************/
150static fault_t
151PutByte (ARMul_State * state, ARMword address, ARMword data)
152{
153 fault_t fault;
154
155 fault = mmu_write_byte (state, address, data);
156 if (fault) {
157//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
158// printf("SKYEYE: PutByte fault %d \n", fault);
159 }
160 return fault;
161}
162
163/***************************************************************************\
164* Put a halfword into Virtual Memory, maybe allocating the page *
165\***************************************************************************/
166static fault_t
167PutHalfWord (ARMul_State * state, ARMword address, ARMword data)
168{
169 fault_t fault;
170
171 fault = mmu_write_halfword (state, address, data);
172 if (fault) {
173//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
174// printf("SKYEYE: PutHalfWord fault %d \n", fault);
175 }
176 return fault;
177}
178
179/***************************************************************************\
180* Put a Word into Virtual Memory, maybe allocating the page *
181\***************************************************************************/
182
183static fault_t
184PutWord (ARMul_State * state, ARMword address, ARMword data)
185{
186 fault_t fault;
187
188 fault = mmu_write_word (state, address, data);
189 if (fault) {
190//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
191#if 0
192/* XXX */ extern int hack;
193 hack = 1;
194#endif
195#if 0
196 printf ("mmu_write_word at 0x%08x: ", address);
197 switch (fault) {
198 case ALIGNMENT_FAULT:
199 printf ("ALIGNMENT_FAULT");
200 break;
201 case SECTION_TRANSLATION_FAULT:
202 printf ("SECTION_TRANSLATION_FAULT");
203 break;
204 case PAGE_TRANSLATION_FAULT:
205 printf ("PAGE_TRANSLATION_FAULT");
206 break;
207 case SECTION_DOMAIN_FAULT:
208 printf ("SECTION_DOMAIN_FAULT");
209 break;
210 case SECTION_PERMISSION_FAULT:
211 printf ("SECTION_PERMISSION_FAULT");
212 break;
213 case SUBPAGE_PERMISSION_FAULT:
214 printf ("SUBPAGE_PERMISSION_FAULT");
215 break;
216 default:
217 printf ("Unrecognized fault number!");
218 }
219 printf ("\tpc = 0x%08x\n", state->Reg[15]);
220#endif
221 }
222 return fault;
223}
224
225/***************************************************************************\
226* Initialise the memory interface *
227\***************************************************************************/
228
229unsigned
230ARMul_MemoryInit (ARMul_State * state, unsigned int initmemsize)
231{
232 return TRUE;
233}
234
235/***************************************************************************\
236* Remove the memory interface *
237\***************************************************************************/
238
239void
240ARMul_MemoryExit (ARMul_State * state)
241{
242}
243
244/***************************************************************************\
245* ReLoad Instruction *
246\***************************************************************************/
247
248ARMword
249ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
250{
251 ARMword data;
252 fault_t fault;
253
254#ifdef ABORTS
255 if (address >= LOWABORT && address < HIGHABORT) {
256 ARMul_PREFETCHABORT (address);
257 return ARMul_ABORTWORD;
258 }
259 else {
260 ARMul_CLEARABORT;
261 }
262#endif
263#if 0
264 /* do profiling for code coverage */
265 if (skyeye_config.code_cov.prof_on)
266 cov_prof(EXEC_FLAG, address);
267#endif
268#if 1
269 if ((isize == 2) && (address & 0x2)) {
270 ARMword lo, hi;
271 if (!(skyeye_cachetype == INSTCACHE))
272 fault = GetHalfWord (state, address, &lo);
273 else
274 fault = LoadInstr (state, address, &lo);
275#if 0
276 if (!fault) {
277 if (!(skyeye_cachetype == INSTCACHE))
278 fault = GetHalfWord (state, address + isize, &hi);
279 else
280 fault = LoadInstr (state, address + isize, &hi);
281
282 }
283#endif
284 if (fault) {
285 ARMul_PREFETCHABORT (address);
286 return ARMul_ABORTWORD;
287 }
288 else {
289 ARMul_CLEARABORT;
290 }
291 return lo;
292#if 0
293 if (state->bigendSig == HIGH)
294 return (lo << 16) | (hi >> 16);
295 else
296 return ((hi & 0xFFFF) << 16) | (lo >> 16);
297#endif
298 }
299#endif
300 if (!(skyeye_cachetype == INSTCACHE))
301 fault = GetWord (state, address, &data);
302 else
303 fault = LoadInstr (state, address, &data);
304
305 if (fault) {
306
307 /* dyf add for s3c6410 no instcache temporary 2010.9.17 */
308 if (!(skyeye_cachetype == INSTCACHE)) {
309 /* set translation fault on prefetch abort */
310 state->mmu.fault_statusi = fault & 0xFF;
311 state->mmu.fault_address = address;
312 }
313 /* add end */
314
315 ARMul_PREFETCHABORT (address);
316 return ARMul_ABORTWORD;
317 }
318 else {
319 ARMul_CLEARABORT;
320 }
321
322 return data;
323}
324
325/***************************************************************************\
326* Load Instruction, Sequential Cycle *
327\***************************************************************************/
328
329ARMword
330ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
331{
332 state->NumScycles++;
333
334#ifdef HOURGLASS
335 if ((state->NumScycles & HOURGLASS_RATE) == 0) {
336 HOURGLASS;
337 }
338#endif
339
340 return ARMul_ReLoadInstr (state, address, isize);
341}
342
343/***************************************************************************\
344* Load Instruction, Non Sequential Cycle *
345\***************************************************************************/
346
347ARMword
348ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
349{
350 state->NumNcycles++;
351
352 return ARMul_ReLoadInstr (state, address, isize);
353}
354
355/***************************************************************************\
356* Read Word (but don't tell anyone!) *
357\***************************************************************************/
358
359ARMword
360ARMul_ReadWord (ARMul_State * state, ARMword address)
361{
362 ARMword data;
363 fault_t fault;
364
365#ifdef ABORTS
366 if (address >= LOWABORT && address < HIGHABORT) {
367 ARMul_DATAABORT (address);
368 return ARMul_ABORTWORD;
369 }
370 else {
371 ARMul_CLEARABORT;
372 }
373#endif
374
375 fault = GetWord (state, address, &data);
376 if (fault) {
377 state->mmu.fault_status =
378 (fault | (state->mmu.last_domain << 4)) & 0xFF;
379 state->mmu.fault_address = address;
380 ARMul_DATAABORT (address);
381 return ARMul_ABORTWORD;
382 }
383 else {
384 ARMul_CLEARABORT;
385 }
386 return data;
387}
388
389/***************************************************************************\
390* Load Word, Sequential Cycle *
391\***************************************************************************/
392
393ARMword
394ARMul_LoadWordS (ARMul_State * state, ARMword address)
395{
396 state->NumScycles++;
397
398 return ARMul_ReadWord (state, address);
399}
400
401/***************************************************************************\
402* Load Word, Non Sequential Cycle *
403\***************************************************************************/
404
405ARMword
406ARMul_LoadWordN (ARMul_State * state, ARMword address)
407{
408 state->NumNcycles++;
409
410 return ARMul_ReadWord (state, address);
411}
412
413/***************************************************************************\
414* Load Halfword, (Non Sequential Cycle) *
415\***************************************************************************/
416
417ARMword
418ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
419{
420 ARMword data;
421 fault_t fault;
422
423 state->NumNcycles++;
424 fault = GetHalfWord (state, address, &data);
425
426 if (fault) {
427 state->mmu.fault_status =
428 (fault | (state->mmu.last_domain << 4)) & 0xFF;
429 state->mmu.fault_address = address;
430 ARMul_DATAABORT (address);
431 return ARMul_ABORTWORD;
432 }
433 else {
434 ARMul_CLEARABORT;
435 }
436
437 return data;
438
439}
440
441/***************************************************************************\
442* Read Byte (but don't tell anyone!) *
443\***************************************************************************/
444int ARMul_ICE_ReadByte(ARMul_State * state, ARMword address, ARMword *presult)
445{
446 ARMword data;
447 fault_t fault;
448 fault = GetByte (state, address, &data);
449 if (fault) {
450 *presult=-1; fault=ALIGNMENT_FAULT; return fault;
451 }else{
452 *(char *)presult=(unsigned char)(data & 0xff); fault=NO_FAULT; return fault;
453 }
454}
455
456
457ARMword
458ARMul_ReadByte (ARMul_State * state, ARMword address)
459{
460 ARMword data;
461 fault_t fault;
462
463 fault = GetByte (state, address, &data);
464
465 if (fault) {
466 state->mmu.fault_status =
467 (fault | (state->mmu.last_domain << 4)) & 0xFF;
468 state->mmu.fault_address = address;
469 ARMul_DATAABORT (address);
470 return ARMul_ABORTWORD;
471 }
472 else {
473 ARMul_CLEARABORT;
474 }
475
476 return data;
477
478}
479
480/***************************************************************************\
481* Load Byte, (Non Sequential Cycle) *
482\***************************************************************************/
483
484ARMword
485ARMul_LoadByte (ARMul_State * state, ARMword address)
486{
487 state->NumNcycles++;
488
489 return ARMul_ReadByte (state, address);
490}
491
492/***************************************************************************\
493* Write Word (but don't tell anyone!) *
494\***************************************************************************/
495
496void
497ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
498{
499 fault_t fault;
500
501#ifdef ABORTS
502 if (address >= LOWABORT && address < HIGHABORT) {
503 ARMul_DATAABORT (address);
504 return;
505 }
506 else {
507 ARMul_CLEARABORT;
508 }
509#endif
510
511 fault = PutWord (state, address, data);
512 if (fault) {
513 state->mmu.fault_status =
514 (fault | (state->mmu.last_domain << 4)) & 0xFF;
515 state->mmu.fault_address = address;
516 ARMul_DATAABORT (address);
517 return;
518 }
519 else {
520 ARMul_CLEARABORT;
521 }
522}
523
524/***************************************************************************\
525* Store Word, Sequential Cycle *
526\***************************************************************************/
527
528void
529ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
530{
531 state->NumScycles++;
532
533 ARMul_WriteWord (state, address, data);
534}
535
536/***************************************************************************\
537* Store Word, Non Sequential Cycle *
538\***************************************************************************/
539
540void
541ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
542{
543 state->NumNcycles++;
544
545 ARMul_WriteWord (state, address, data);
546}
547
548/***************************************************************************\
549* Store HalfWord, (Non Sequential Cycle) *
550\***************************************************************************/
551
552void
553ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
554{
555 fault_t fault;
556 state->NumNcycles++;
557 fault = PutHalfWord (state, address, data);
558 if (fault) {
559 state->mmu.fault_status =
560 (fault | (state->mmu.last_domain << 4)) & 0xFF;
561 state->mmu.fault_address = address;
562 ARMul_DATAABORT (address);
563 return;
564 }
565 else {
566 ARMul_CLEARABORT;
567 }
568}
569
570//chy 2006-04-15
571int ARMul_ICE_WriteByte (ARMul_State * state, ARMword address, ARMword data)
572{
573 fault_t fault;
574 fault = PutByte (state, address, data);
575 if (fault)
576 return 1;
577 else
578 return 0;
579}
580/***************************************************************************\
581* Write Byte (but don't tell anyone!) *
582\***************************************************************************/
583//chy 2003-07-10, add real write byte fun
584void
585ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
586{
587 fault_t fault;
588 fault = PutByte (state, address, data);
589 if (fault) {
590 state->mmu.fault_status =
591 (fault | (state->mmu.last_domain << 4)) & 0xFF;
592 state->mmu.fault_address = address;
593 ARMul_DATAABORT (address);
594 return;
595 }
596 else {
597 ARMul_CLEARABORT;
598 }
599}
600
601/***************************************************************************\
602* Store Byte, (Non Sequential Cycle) *
603\***************************************************************************/
604
605void
606ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
607{
608 state->NumNcycles++;
609
610#ifdef VALIDATE
611 if (address == TUBE) {
612 if (data == 4)
613 state->Emulate = FALSE;
614 else
615 (void) putc ((char) data, stderr); /* Write Char */
616 return;
617 }
618#endif
619
620 ARMul_WriteByte (state, address, data);
621}
622
623/***************************************************************************\
624* Swap Word, (Two Non Sequential Cycles) *
625\***************************************************************************/
626
627ARMword
628ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
629{
630 ARMword temp;
631
632 state->NumNcycles++;
633
634 temp = ARMul_ReadWord (state, address);
635
636 state->NumNcycles++;
637
638 PutWord (state, address, data);
639
640 return temp;
641}
642
643/***************************************************************************\
644* Swap Byte, (Two Non Sequential Cycles) *
645\***************************************************************************/
646
647ARMword
648ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
649{
650 ARMword temp;
651
652 temp = ARMul_LoadByte (state, address);
653 ARMul_StoreByte (state, address, data);
654
655 return temp;
656}
657
658/***************************************************************************\
659* Count I Cycles *
660\***************************************************************************/
661
662void
663ARMul_Icycles (ARMul_State * state, unsigned number,
664 ARMword address)
665{
666 state->NumIcycles += number;
667 ARMul_CLEARABORT;
668}
669
670/***************************************************************************\
671* Count C Cycles *
672\***************************************************************************/
673
674void
675ARMul_Ccycles (ARMul_State * state, unsigned number,
676 ARMword address)
677{
678 state->NumCcycles += number;
679 ARMul_CLEARABORT;
680}