diff options
Diffstat (limited to 'src/core/arm/interpreter/arminit.cpp')
| -rw-r--r-- | src/core/arm/interpreter/arminit.cpp | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp new file mode 100644 index 000000000..f48232eec --- /dev/null +++ b/src/core/arm/interpreter/arminit.cpp | |||
| @@ -0,0 +1,579 @@ | |||
| 1 | /* arminit.c -- ARMulator initialization: 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 | |||
| 19 | #include "platform.h" | ||
| 20 | #if EMU_PLATFORM == PLATFORM_LINUX | ||
| 21 | #include <unistd.h> | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #include <math.h> | ||
| 25 | |||
| 26 | #include "armdefs.h" | ||
| 27 | #include "armemu.h" | ||
| 28 | |||
| 29 | /***************************************************************************\ | ||
| 30 | * Definitions for the emulator architecture * | ||
| 31 | \***************************************************************************/ | ||
| 32 | |||
| 33 | void ARMul_EmulateInit (void); | ||
| 34 | ARMul_State *ARMul_NewState (ARMul_State * state); | ||
| 35 | void ARMul_Reset (ARMul_State * state); | ||
| 36 | ARMword ARMul_DoCycle (ARMul_State * state); | ||
| 37 | unsigned ARMul_DoCoPro (ARMul_State * state); | ||
| 38 | ARMword ARMul_DoProg (ARMul_State * state); | ||
| 39 | ARMword ARMul_DoInstr (ARMul_State * state); | ||
| 40 | void ARMul_Abort (ARMul_State * state, ARMword address); | ||
| 41 | |||
| 42 | unsigned ARMul_MultTable[32] = | ||
| 43 | { 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, | ||
| 44 | 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16 | ||
| 45 | }; | ||
| 46 | ARMword ARMul_ImmedTable[4096]; /* immediate DP LHS values */ | ||
| 47 | char ARMul_BitList[256]; /* number of bits in a byte table */ | ||
| 48 | |||
| 49 | //chy 2006-02-22 add test debugmode | ||
| 50 | extern int debugmode; | ||
| 51 | extern int remote_interrupt( void ); | ||
| 52 | |||
| 53 | |||
| 54 | void arm_dyncom_Abort(ARMul_State * state, ARMword vector) | ||
| 55 | { | ||
| 56 | ARMul_Abort(state, vector); | ||
| 57 | } | ||
| 58 | |||
| 59 | |||
| 60 | /* ahe-ykl : the following code to initialize user mode | ||
| 61 | code is architecture dependent and probably model dependant. */ | ||
| 62 | |||
| 63 | //#include "skyeye_arch.h" | ||
| 64 | //#include "skyeye_pref.h" | ||
| 65 | //#include "skyeye_exec_info.h" | ||
| 66 | //#include "bank_defs.h" | ||
| 67 | #include "armcpu.h" | ||
| 68 | //#include "skyeye_callback.h" | ||
| 69 | |||
| 70 | //void arm_user_mode_init(generic_arch_t * arch_instance) | ||
| 71 | //{ | ||
| 72 | // sky_pref_t *pref = get_skyeye_pref(); | ||
| 73 | // | ||
| 74 | // if (pref->user_mode_sim) | ||
| 75 | // { | ||
| 76 | // sky_exec_info_t *info = get_skyeye_exec_info(); | ||
| 77 | // info->arch_page_size = 0x1000; | ||
| 78 | // info->arch_stack_top = 0x1ffffff0;// + 0x401fe7 - 0xff0; /* arbitrary value */ | ||
| 79 | // /* stack initial address specific to architecture may be placed here */ | ||
| 80 | // | ||
| 81 | // /* we need to mmap the stack space, if we are using skyeye space */ | ||
| 82 | // if (info->mmap_access) | ||
| 83 | // { | ||
| 84 | // /* get system stack size */ | ||
| 85 | // size_t stacksize = 0; | ||
| 86 | // pthread_attr_t attr; | ||
| 87 | // pthread_attr_init(&attr); | ||
| 88 | // pthread_attr_getstacksize(&attr, &stacksize); | ||
| 89 | // if (stacksize > info->arch_stack_top) | ||
| 90 | // { | ||
| 91 | // printf("arch_stack_top is too low\n"); | ||
| 92 | // stacksize = info->arch_stack_top; | ||
| 93 | // } | ||
| 94 | // | ||
| 95 | // /* Note: Skyeye is occupating 0x400000 to 0x600000 */ | ||
| 96 | // /* We do a mmap */ | ||
| 97 | // void* ret = mmap( (info->arch_stack_top) - stacksize, | ||
| 98 | // stacksize + 0x1000 , PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
| 99 | // if (ret == MAP_FAILED){ | ||
| 100 | // /* ideally, we should find an empty space until it works */ | ||
| 101 | // printf("mmap error, stack couldn't be mapped: errno %d\n", errno); | ||
| 102 | // exit(-1); | ||
| 103 | // } else { | ||
| 104 | // memset(ret, '\0', stacksize); | ||
| 105 | // //printf("stack top has been defined at %x size %x\n", (uint32_t) ret + stacksize, stacksize); | ||
| 106 | // //info->arch_stack_top = (uint32_t) ret + stacksize; | ||
| 107 | // } | ||
| 108 | // } | ||
| 109 | // | ||
| 110 | // exec_stack_init(); | ||
| 111 | // | ||
| 112 | // ARM_CPU_State* cpu = get_current_cpu(); | ||
| 113 | // arm_core_t* core = &cpu->core[0]; | ||
| 114 | // | ||
| 115 | // uint32_t sp = info->initial_sp; | ||
| 116 | // | ||
| 117 | // core->Cpsr = 0x10; /* User mode */ | ||
| 118 | // /* FIXME: may need to add thumb */ | ||
| 119 | // core->Reg[13] = sp; | ||
| 120 | // core->Reg[10] = info->start_data; | ||
| 121 | // core->Reg[0] = 0; | ||
| 122 | // bus_read(32, sp + 4, &(core->Reg[1])); | ||
| 123 | // bus_read(32, sp + 8, &(core->Reg[2])); | ||
| 124 | // } | ||
| 125 | // | ||
| 126 | //} | ||
| 127 | |||
| 128 | /***************************************************************************\ | ||
| 129 | * Call this routine once to set up the emulator's tables. * | ||
| 130 | \***************************************************************************/ | ||
| 131 | |||
| 132 | void | ||
| 133 | ARMul_EmulateInit (void) | ||
| 134 | { | ||
| 135 | unsigned int i, j; | ||
| 136 | |||
| 137 | for (i = 0; i < 4096; i++) { /* the values of 12 bit dp rhs's */ | ||
| 138 | ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL); | ||
| 139 | } | ||
| 140 | |||
| 141 | for (i = 0; i < 256; ARMul_BitList[i++] = 0); /* how many bits in LSM */ | ||
| 142 | for (j = 1; j < 256; j <<= 1) | ||
| 143 | for (i = 0; i < 256; i++) | ||
| 144 | if ((i & j) > 0) | ||
| 145 | ARMul_BitList[i]++; | ||
| 146 | |||
| 147 | for (i = 0; i < 256; i++) | ||
| 148 | ARMul_BitList[i] *= 4; /* you always need 4 times these values */ | ||
| 149 | |||
| 150 | } | ||
| 151 | |||
| 152 | /***************************************************************************\ | ||
| 153 | * Returns a new instantiation of the ARMulator's state * | ||
| 154 | \***************************************************************************/ | ||
| 155 | |||
| 156 | ARMul_State * | ||
| 157 | ARMul_NewState (ARMul_State *state) | ||
| 158 | { | ||
| 159 | unsigned i, j; | ||
| 160 | |||
| 161 | memset (state, 0, sizeof (ARMul_State)); | ||
| 162 | |||
| 163 | state->Emulate = RUN; | ||
| 164 | for (i = 0; i < 16; i++) { | ||
| 165 | state->Reg[i] = 0; | ||
| 166 | for (j = 0; j < 7; j++) | ||
| 167 | state->RegBank[j][i] = 0; | ||
| 168 | } | ||
| 169 | for (i = 0; i < 7; i++) | ||
| 170 | state->Spsr[i] = 0; | ||
| 171 | state->Mode = 0; | ||
| 172 | |||
| 173 | state->CallDebug = FALSE; | ||
| 174 | state->Debug = FALSE; | ||
| 175 | state->VectorCatch = 0; | ||
| 176 | state->Aborted = FALSE; | ||
| 177 | state->Reseted = FALSE; | ||
| 178 | state->Inted = 3; | ||
| 179 | state->LastInted = 3; | ||
| 180 | |||
| 181 | state->CommandLine = NULL; | ||
| 182 | |||
| 183 | state->EventSet = 0; | ||
| 184 | state->Now = 0; | ||
| 185 | state->EventPtr = | ||
| 186 | (struct EventNode **) malloc ((unsigned) EVENTLISTSIZE * | ||
| 187 | sizeof (struct EventNode *)); | ||
| 188 | #if DIFF_STATE | ||
| 189 | state->state_log = fopen("/data/state.log", "w"); | ||
| 190 | printf("create pc log file.\n"); | ||
| 191 | #endif | ||
| 192 | if (state->EventPtr == NULL) { | ||
| 193 | printf ("SKYEYE: ARMul_NewState malloc state->EventPtr error\n"); | ||
| 194 | exit(-1); | ||
| 195 | } | ||
| 196 | for (i = 0; i < EVENTLISTSIZE; i++) | ||
| 197 | *(state->EventPtr + i) = NULL; | ||
| 198 | #if SAVE_LOG | ||
| 199 | state->state_log = fopen("/tmp/state.log", "w"); | ||
| 200 | printf("create pc log file.\n"); | ||
| 201 | #else | ||
| 202 | #if DIFF_LOG | ||
| 203 | state->state_log = fopen("/tmp/state.log", "r"); | ||
| 204 | printf("loaded pc log file.\n"); | ||
| 205 | #endif | ||
| 206 | #endif | ||
| 207 | |||
| 208 | #ifdef ARM61 | ||
| 209 | state->prog32Sig = LOW; | ||
| 210 | state->data32Sig = LOW; | ||
| 211 | #else | ||
| 212 | state->prog32Sig = HIGH; | ||
| 213 | state->data32Sig = HIGH; | ||
| 214 | #endif | ||
| 215 | |||
| 216 | state->lateabtSig = HIGH; | ||
| 217 | state->bigendSig = LOW; | ||
| 218 | |||
| 219 | //chy:2003-08-19 | ||
| 220 | state->LastTime = 0; | ||
| 221 | state->CP14R0_CCD = -1; | ||
| 222 | |||
| 223 | /* ahe-ykl: common function for interpret and dyncom */ | ||
| 224 | //sky_pref_t *pref = get_skyeye_pref(); | ||
| 225 | //if (pref->user_mode_sim) | ||
| 226 | // register_callback(arm_user_mode_init, Bootmach_callback); | ||
| 227 | |||
| 228 | memset(&state->exclusive_tag_array[0], 0xFF, sizeof(state->exclusive_tag_array[0]) * 128); | ||
| 229 | state->exclusive_access_state = 0; | ||
| 230 | //state->cpu = (cpu_config_t *) malloc (sizeof (cpu_config_t)); | ||
| 231 | //state->mem_bank = (mem_config_t *) malloc (sizeof (mem_config_t)); | ||
| 232 | return (state); | ||
| 233 | } | ||
| 234 | |||
| 235 | /***************************************************************************\ | ||
| 236 | * Call this routine to set ARMulator to model a certain processor * | ||
| 237 | \***************************************************************************/ | ||
| 238 | |||
| 239 | void | ||
| 240 | ARMul_SelectProcessor (ARMul_State * state, unsigned properties) | ||
| 241 | { | ||
| 242 | if (properties & ARM_Fix26_Prop) { | ||
| 243 | state->prog32Sig = LOW; | ||
| 244 | state->data32Sig = LOW; | ||
| 245 | } | ||
| 246 | else { | ||
| 247 | state->prog32Sig = HIGH; | ||
| 248 | state->data32Sig = HIGH; | ||
| 249 | } | ||
| 250 | /* 2004-05-09 chy | ||
| 251 | below line sould be in skyeye_mach_XXX.c 's XXX_mach_init function | ||
| 252 | */ | ||
| 253 | // state->lateabtSig = HIGH; | ||
| 254 | |||
| 255 | |||
| 256 | state->is_v4 = | ||
| 257 | (properties & (ARM_v4_Prop | ARM_v5_Prop)) ? HIGH : LOW; | ||
| 258 | state->is_v5 = (properties & ARM_v5_Prop) ? HIGH : LOW; | ||
| 259 | state->is_v5e = (properties & ARM_v5e_Prop) ? HIGH : LOW; | ||
| 260 | state->is_XScale = (properties & ARM_XScale_Prop) ? HIGH : LOW; | ||
| 261 | state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) ? HIGH : LOW; | ||
| 262 | /* state->is_v6 = LOW */; | ||
| 263 | /* jeff.du 2010-08-05 */ | ||
| 264 | state->is_v6 = (properties & ARM_v6_Prop) ? HIGH : LOW; | ||
| 265 | state->is_ep9312 = (properties & ARM_ep9312_Prop) ? HIGH : LOW; | ||
| 266 | //chy 2005-09-19 | ||
| 267 | state->is_pxa27x = (properties & ARM_PXA27X_Prop) ? HIGH : LOW; | ||
| 268 | |||
| 269 | /* shenoubang 2012-3-11 */ | ||
| 270 | state->is_v7 = (properties & ARM_v7_Prop) ? HIGH : LOW; | ||
| 271 | |||
| 272 | /* Only initialse the coprocessor support once we | ||
| 273 | know what kind of chip we are dealing with. */ | ||
| 274 | //ARMul_CoProInit (state); Commented out /bunnei | ||
| 275 | |||
| 276 | } | ||
| 277 | |||
| 278 | /***************************************************************************\ | ||
| 279 | * Call this routine to set up the initial machine state (or perform a RESET * | ||
| 280 | \***************************************************************************/ | ||
| 281 | |||
| 282 | void | ||
| 283 | ARMul_Reset (ARMul_State * state) | ||
| 284 | { | ||
| 285 | //fprintf(stderr,"armul_reset 0: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); | ||
| 286 | state->NextInstr = 0; | ||
| 287 | if (state->prog32Sig) { | ||
| 288 | state->Reg[15] = 0; | ||
| 289 | state->Cpsr = INTBITS | SVC32MODE; | ||
| 290 | state->Mode = SVC32MODE; | ||
| 291 | } | ||
| 292 | else { | ||
| 293 | state->Reg[15] = R15INTBITS | SVC26MODE; | ||
| 294 | state->Cpsr = INTBITS | SVC26MODE; | ||
| 295 | state->Mode = SVC26MODE; | ||
| 296 | } | ||
| 297 | //fprintf(stderr,"armul_reset 1: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); | ||
| 298 | ARMul_CPSRAltered (state); | ||
| 299 | state->Bank = SVCBANK; | ||
| 300 | FLUSHPIPE; | ||
| 301 | |||
| 302 | state->EndCondition = 0; | ||
| 303 | state->ErrorCode = 0; | ||
| 304 | |||
| 305 | //fprintf(stderr,"armul_reset 2: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); | ||
| 306 | state->NresetSig = HIGH; | ||
| 307 | state->NfiqSig = HIGH; | ||
| 308 | state->NirqSig = HIGH; | ||
| 309 | state->NtransSig = (state->Mode & 3) ? HIGH : LOW; | ||
| 310 | state->abortSig = LOW; | ||
| 311 | state->AbortAddr = 1; | ||
| 312 | |||
| 313 | state->NumInstrs = 0; | ||
| 314 | state->NumNcycles = 0; | ||
| 315 | state->NumScycles = 0; | ||
| 316 | state->NumIcycles = 0; | ||
| 317 | state->NumCcycles = 0; | ||
| 318 | state->NumFcycles = 0; | ||
| 319 | |||
| 320 | //fprintf(stderr,"armul_reset 3: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); | ||
| 321 | //mmu_reset (state); Commented out /bunnei | ||
| 322 | //fprintf(stderr,"armul_reset 4: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); | ||
| 323 | |||
| 324 | //mem_reset (state); /* move to memory/ram.c */ | ||
| 325 | |||
| 326 | //fprintf(stderr,"armul_reset 5: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); | ||
| 327 | /*remove later. walimis 03.7.17 */ | ||
| 328 | //io_reset(state); | ||
| 329 | //lcd_disable(state); | ||
| 330 | |||
| 331 | /*ywc 2005-04-07 move from ARMul_NewState , because skyeye_config.no_dbct will | ||
| 332 | *be configured in skyeye_option_init and it is called after ARMul_NewState*/ | ||
| 333 | state->tea_break_ok = 0; | ||
| 334 | state->tea_break_addr = 0; | ||
| 335 | state->tea_pc = 0; | ||
| 336 | #ifdef DBCT | ||
| 337 | if (!skyeye_config.no_dbct) { | ||
| 338 | //teawater add for arm2x86 2005.02.14------------------------------------------- | ||
| 339 | if (arm2x86_init (state)) { | ||
| 340 | printf ("SKYEYE: arm2x86_init error\n"); | ||
| 341 | skyeye_exit (-1); | ||
| 342 | } | ||
| 343 | //AJ2D-------------------------------------------------------------------------- | ||
| 344 | } | ||
| 345 | #endif | ||
| 346 | } | ||
| 347 | |||
| 348 | |||
| 349 | /***************************************************************************\ | ||
| 350 | * Emulate the execution of an entire program. Start the correct emulator * | ||
| 351 | * (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * | ||
| 352 | * address of the last instruction that is executed. * | ||
| 353 | \***************************************************************************/ | ||
| 354 | |||
| 355 | //teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- | ||
| 356 | #ifdef DBCT_TEST_SPEED | ||
| 357 | static ARMul_State *dbct_test_speed_state = NULL; | ||
| 358 | static void | ||
| 359 | dbct_test_speed_sig(int signo) | ||
| 360 | { | ||
| 361 | printf("\n0x%llx %llu\n", dbct_test_speed_state->instr_count, dbct_test_speed_state->instr_count); | ||
| 362 | skyeye_exit(0); | ||
| 363 | } | ||
| 364 | #endif //DBCT_TEST_SPEED | ||
| 365 | //AJ2D-------------------------------------------------------------------------- | ||
| 366 | |||
| 367 | ARMword | ||
| 368 | ARMul_DoProg (ARMul_State * state) | ||
| 369 | { | ||
| 370 | ARMword pc = 0; | ||
| 371 | |||
| 372 | /* | ||
| 373 | * 2007-01-24 removed the term-io functions by Anthony Lee, | ||
| 374 | * moved to "device/uart/skyeye_uart_stdio.c". | ||
| 375 | */ | ||
| 376 | |||
| 377 | //teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- | ||
| 378 | #ifdef DBCT_TEST_SPEED | ||
| 379 | { | ||
| 380 | if (!dbct_test_speed_state) { | ||
| 381 | //init timer | ||
| 382 | struct itimerval value; | ||
| 383 | struct sigaction act; | ||
| 384 | |||
| 385 | dbct_test_speed_state = state; | ||
| 386 | state->instr_count = 0; | ||
| 387 | act.sa_handler = dbct_test_speed_sig; | ||
| 388 | act.sa_flags = SA_RESTART; | ||
| 389 | //cygwin don't support ITIMER_VIRTUAL or ITIMER_PROF | ||
| 390 | #ifndef __CYGWIN__ | ||
| 391 | if (sigaction(SIGVTALRM, &act, NULL) == -1) { | ||
| 392 | #else | ||
| 393 | if (sigaction(SIGALRM, &act, NULL) == -1) { | ||
| 394 | #endif //__CYGWIN__ | ||
| 395 | fprintf(stderr, "init timer error.\n"); | ||
| 396 | skyeye_exit(-1); | ||
| 397 | } | ||
| 398 | if (skyeye_config.dbct_test_speed_sec) { | ||
| 399 | value.it_value.tv_sec = skyeye_config.dbct_test_speed_sec; | ||
| 400 | } | ||
| 401 | else { | ||
| 402 | value.it_value.tv_sec = DBCT_TEST_SPEED_SEC; | ||
| 403 | } | ||
| 404 | printf("dbct_test_speed_sec = %ld\n", value.it_value.tv_sec); | ||
| 405 | value.it_value.tv_usec = 0; | ||
| 406 | value.it_interval.tv_sec = 0; | ||
| 407 | value.it_interval.tv_usec = 0; | ||
| 408 | #ifndef __CYGWIN__ | ||
| 409 | if (setitimer(ITIMER_VIRTUAL, &value, NULL) == -1) { | ||
| 410 | #else | ||
| 411 | if (setitimer(ITIMER_REAL, &value, NULL) == -1) { | ||
| 412 | #endif //__CYGWIN__ | ||
| 413 | fprintf(stderr, "init timer error.\n"); | ||
| 414 | skyeye_exit(-1); | ||
| 415 | } | ||
| 416 | } | ||
| 417 | } | ||
| 418 | #endif //DBCT_TEST_SPEED | ||
| 419 | //AJ2D-------------------------------------------------------------------------- | ||
| 420 | state->Emulate = RUN; | ||
| 421 | while (state->Emulate != STOP) { | ||
| 422 | state->Emulate = RUN; | ||
| 423 | |||
| 424 | /*ywc 2005-03-31 */ | ||
| 425 | if (state->prog32Sig && ARMul_MODE32BIT) { | ||
| 426 | #ifdef DBCT | ||
| 427 | if (skyeye_config.no_dbct) { | ||
| 428 | pc = ARMul_Emulate32 (state); | ||
| 429 | } | ||
| 430 | else { | ||
| 431 | pc = ARMul_Emulate32_dbct (state); | ||
| 432 | } | ||
| 433 | #else | ||
| 434 | pc = ARMul_Emulate32 (state); | ||
| 435 | #endif | ||
| 436 | } | ||
| 437 | |||
| 438 | else { | ||
| 439 | _dbg_assert_msg_(ARM11, false, "Unsupported ARM 26-bit Mode!"); | ||
| 440 | } | ||
| 441 | //chy 2006-02-22, should test debugmode first | ||
| 442 | //chy 2006-04-14, put below codes in ARMul_Emulate | ||
| 443 | #if 0 | ||
| 444 | if(debugmode) | ||
| 445 | if(remote_interrupt()) | ||
| 446 | state->Emulate = STOP; | ||
| 447 | #endif | ||
| 448 | } | ||
| 449 | |||
| 450 | /* | ||
| 451 | * 2007-01-24 removed the term-io functions by Anthony Lee, | ||
| 452 | * moved to "device/uart/skyeye_uart_stdio.c". | ||
| 453 | */ | ||
| 454 | |||
| 455 | return (pc); | ||
| 456 | } | ||
| 457 | |||
| 458 | /***************************************************************************\ | ||
| 459 | * Emulate the execution of one instruction. Start the correct emulator * | ||
| 460 | * (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * | ||
| 461 | * address of the instruction that is executed. * | ||
| 462 | \***************************************************************************/ | ||
| 463 | |||
| 464 | ARMword | ||
| 465 | ARMul_DoInstr (ARMul_State * state) | ||
| 466 | { | ||
| 467 | ARMword pc = 0; | ||
| 468 | |||
| 469 | state->Emulate = ONCE; | ||
| 470 | |||
| 471 | /*ywc 2005-03-31 */ | ||
| 472 | if (state->prog32Sig && ARMul_MODE32BIT) { | ||
| 473 | #ifdef DBCT | ||
| 474 | if (skyeye_config.no_dbct) { | ||
| 475 | pc = ARMul_Emulate32 (state); | ||
| 476 | } | ||
| 477 | else { | ||
| 478 | //teawater add compile switch for DBCT GDB RSP function 2005.10.21-------------- | ||
| 479 | #ifndef DBCT_GDBRSP | ||
| 480 | printf("DBCT GDBRSP function switch is off.\n"); | ||
| 481 | printf("To use this function, open \"#define DBCT_GDBRSP\" in arch/arm/common/armdefs.h & recompile skyeye.\n"); | ||
| 482 | skyeye_exit(-1); | ||
| 483 | #endif //DBCT_GDBRSP | ||
| 484 | //AJ2D-------------------------------------------------------------------------- | ||
| 485 | pc = ARMul_Emulate32_dbct (state); | ||
| 486 | } | ||
| 487 | #else | ||
| 488 | pc = ARMul_Emulate32 (state); | ||
| 489 | #endif | ||
| 490 | } | ||
| 491 | |||
| 492 | else { | ||
| 493 | _dbg_assert_msg_(ARM11, false, "Unsupported ARM 26-bit Mode!"); | ||
| 494 | } | ||
| 495 | |||
| 496 | return (pc); | ||
| 497 | } | ||
| 498 | |||
| 499 | /***************************************************************************\ | ||
| 500 | * This routine causes an Abort to occur, including selecting the correct * | ||
| 501 | * mode, register bank, and the saving of registers. Call with the * | ||
| 502 | * appropriate vector's memory address (0,4,8 ....) * | ||
| 503 | \***************************************************************************/ | ||
| 504 | |||
| 505 | void | ||
| 506 | ARMul_Abort (ARMul_State * state, ARMword vector) | ||
| 507 | { | ||
| 508 | ARMword temp; | ||
| 509 | int isize = INSN_SIZE; | ||
| 510 | int esize = (TFLAG ? 0 : 4); | ||
| 511 | int e2size = (TFLAG ? -4 : 0); | ||
| 512 | |||
| 513 | state->Aborted = FALSE; | ||
| 514 | |||
| 515 | if (state->prog32Sig) | ||
| 516 | if (ARMul_MODE26BIT) | ||
| 517 | temp = R15PC; | ||
| 518 | else | ||
| 519 | temp = state->Reg[15]; | ||
| 520 | else | ||
| 521 | temp = R15PC | ECC | ER15INT | EMODE; | ||
| 522 | |||
| 523 | switch (vector) { | ||
| 524 | case ARMul_ResetV: /* RESET */ | ||
| 525 | SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE, | ||
| 526 | 0); | ||
| 527 | break; | ||
| 528 | case ARMul_UndefinedInstrV: /* Undefined Instruction */ | ||
| 529 | SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE, | ||
| 530 | isize); | ||
| 531 | break; | ||
| 532 | case ARMul_SWIV: /* Software Interrupt */ | ||
| 533 | SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE, | ||
| 534 | isize); | ||
| 535 | break; | ||
| 536 | case ARMul_PrefetchAbortV: /* Prefetch Abort */ | ||
| 537 | state->AbortAddr = 1; | ||
| 538 | SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, | ||
| 539 | esize); | ||
| 540 | break; | ||
| 541 | case ARMul_DataAbortV: /* Data Abort */ | ||
| 542 | SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, | ||
| 543 | e2size); | ||
| 544 | break; | ||
| 545 | case ARMul_AddrExceptnV: /* Address Exception */ | ||
| 546 | SETABORT (IBIT, SVC26MODE, isize); | ||
| 547 | break; | ||
| 548 | case ARMul_IRQV: /* IRQ */ | ||
| 549 | //chy 2003-09-02 the if sentence seems no use | ||
| 550 | #if 0 | ||
| 551 | if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp) | ||
| 552 | || (temp & ARMul_CP13_R0_IRQ)) | ||
| 553 | #endif | ||
| 554 | SETABORT (IBIT, | ||
| 555 | state->prog32Sig ? IRQ32MODE : IRQ26MODE, | ||
| 556 | esize); | ||
| 557 | break; | ||
| 558 | case ARMul_FIQV: /* FIQ */ | ||
| 559 | //chy 2003-09-02 the if sentence seems no use | ||
| 560 | #if 0 | ||
| 561 | if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp) | ||
| 562 | || (temp & ARMul_CP13_R0_FIQ)) | ||
| 563 | #endif | ||
| 564 | SETABORT (INTBITS, | ||
| 565 | state->prog32Sig ? FIQ32MODE : FIQ26MODE, | ||
| 566 | esize); | ||
| 567 | break; | ||
| 568 | } | ||
| 569 | |||
| 570 | if (ARMul_MODE32BIT) { | ||
| 571 | if (state->mmu.control & CONTROL_VECTOR) | ||
| 572 | vector += 0xffff0000; //for v4 high exception address | ||
| 573 | if (state->vector_remap_flag) | ||
| 574 | vector += state->vector_remap_addr; /* support some remap function in LPC processor */ | ||
| 575 | ARMul_SetR15 (state, vector); | ||
| 576 | } | ||
| 577 | else | ||
| 578 | ARMul_SetR15 (state, R15CCINTMODE | vector); | ||
| 579 | } | ||