ARM11_RC_WDTR,
ARM11_RC_RDTR,
-
ARM11_RC_MAX,
};
/* add further reset initialization here */
+ arm11->simulate_reset_on_next_halt = true;
+
if (*dscr & ARM11_DSCR_CORE_HALTED)
{
+ /** \todo TODO: this needs further scrutiny because
+ * arm11_on_enter_debug_state() never gets properly called
+ */
+
arm11->target->state = TARGET_HALTED;
arm11->target->debug_reason = arm11_get_DSCR_debug_reason(*dscr);
}
arm11_write_DSCR(arm11, new_dscr);
-// jtag_execute_queue();
-
-
-
-// DEBUG("SAVE DSCR %08x", R(DSCR));
-
-// if (R(DSCR) & ARM11_DSCR_WDTR_FULL)
-// DEBUG("SAVE wDTR %08x", R(WDTR));
-
/* From the spec:
Before executing any instruction in debug state you have to drain the write buffer.
arm11->reg_values[ARM11_RC_PC] -= 8;
}
-// DEBUG("SAVE PC %08x", R(PC));
+ if (arm11->simulate_reset_on_next_halt)
+ {
+ arm11->simulate_reset_on_next_halt = false;
+
+ DEBUG("Reset c1 Control Register");
+
+ /* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */
+
+ /* MCR p15,0,R0,c1,c0,0 */
+ arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0);
+
+ }
+
+
arm11_run_instr_data_finish(arm11);
/* MRC p14,0,r?,c0,c5,0 */
arm11_run_instr_data_to_core1(arm11, 0xee100e15 | (i << 12), R(RX + i));
-// DEBUG("RESTORE R%d %08x", i, R(RX + i));
+// DEBUG("RESTORE R" ZU " %08x", i, R(RX + i));
}}
arm11_run_instr_data_finish(arm11);
DEBUG("target->state: %s", target_state_strings[target->state]);
+ if (target->state == TARGET_UNKNOWN)
+ {
+ arm11->simulate_reset_on_next_halt = true;
+ }
+
if (target->state == TARGET_HALTED)
{
WARNING("target was already halted");
if (!current)
R(PC) = address;
- INFO("RESUME PC %08x", R(PC));
+ INFO("RESUME PC %08x%s", R(PC), !current ? "!" : "");
/* clear breakpoints/watchpoints and VCR*/
arm11_sc7_clear_vbw(arm11);
arm11_sc7_run(arm11, brp, asizeof(brp));
- DEBUG("Add BP %d at %08x", brp_num, bp->address);
+ DEBUG("Add BP " ZU " at %08x", brp_num, bp->address);
brp_num++;
}
if (!current)
R(PC) = address;
- INFO("STEP PC %08x", R(PC));
+ INFO("STEP PC %08x%s", R(PC), !current ? "!" : "");
/** \todo TODO: Thumb not supported here */
arm11_read_memory_word(arm11, R(PC), &next_instruction);
- /** skip over BKPT */
+ /* skip over BKPT */
if ((next_instruction & 0xFFF00070) == 0xe1200070)
{
R(PC) += 4;
arm11->reg_list[ARM11_RC_PC].dirty = 0;
INFO("Skipping BKPT");
}
+ /* skip over Wait for interrupt / Standby */
+ /* mcr 15, 0, r?, cr7, cr0, {4} */
+ else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90)
+ {
+ R(PC) += 4;
+ arm11->reg_list[ARM11_RC_PC].valid = 1;
+ arm11->reg_list[ARM11_RC_PC].dirty = 0;
+ INFO("Skipping WFI");
+ }
/* ignore B to self */
else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
{
/** \todo TODO: check if dirty is the right choice to force a rewrite on arm11_resume() */
arm11->reg_list[ARM11_RC_R1].dirty = 1;
- while (count--)
+ {size_t i;
+ for (i = 0; i < count; i++)
{
/* ldrb r1, [r0], #1 */
arm11_run_instr_no_data1(arm11, 0xe4d01001);
arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
*buffer++ = res;
- }
+ }}
+
break;
case 2:
u16 * buf16 = (u16*)buffer;
- while (count--)
+ {size_t i;
+ for (i = 0; i < count; i++)
{
/* ldrh r1, [r0], #2 */
arm11_run_instr_no_data1(arm11, 0xe0d010b2);
arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
*buf16++ = res;
- }
+ }}
+
break;
}
switch (size)
{
case 1:
+ {
arm11->reg_list[ARM11_RC_R1].dirty = 1;
- while (count--)
+ {size_t i;
+ for (i = 0; i < count; i++)
{
/* MRC p14,0,r1,c0,c5,0 */
arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);
/* strb r1, [r0], #1 */
arm11_run_instr_no_data1(arm11, 0xe4c01001);
- }
+ }}
+
break;
+ }
case 2:
{
u16 * buf16 = (u16*)buffer;
- while (count--)
+ {size_t i;
+ for (i = 0; i < count; i++)
{
/* MRC p14,0,r1,c0,c5,0 */
arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buf16++);
/* strh r1, [r0], #2 */
arm11_run_instr_no_data1(arm11, 0xe0c010b2);
- }
+ }}
+
break;
}
ARM11_REGCACHE_COUNT != asizeof(arm11_reg_defs) ||
ARM11_REGCACHE_COUNT != ARM11_RC_MAX)
{
- ERROR("arm11->reg_values inconsistent (%d %d %d %d)", ARM11_REGCACHE_COUNT, asizeof(arm11->reg_values), asizeof(arm11_reg_defs), ARM11_RC_MAX);
+ ERROR("arm11->reg_values inconsistent (%d " ZU " " ZU " %d)", ARM11_REGCACHE_COUNT, asizeof(arm11->reg_values), asizeof(arm11_reg_defs), ARM11_RC_MAX);
exit(-1);
}