]> git.sur5r.net Git - openocd/blobdiff - src/target/cortex_a8.c
Cortex-A8: mode support
[openocd] / src / target / cortex_a8.c
index fd8072325ef3f5367c5893c62d6e7c57ae6a23d1..01b7aee808b931d8482fe958a1e4a4b0f8877c5b 100644 (file)
 #include "config.h"
 #endif
 
+#include "breakpoints.h"
 #include "cortex_a8.h"
-#include "armv7a.h"
-#include "armv4_5.h"
-
+#include "register.h"
 #include "target_request.h"
 #include "target_type.h"
 
-/* cli handling */
-int cortex_a8_register_commands(struct command_context_s *cmd_ctx);
-
-/* forward declarations */
-int cortex_a8_target_create(struct target_s *target, Jim_Interp *interp);
-int cortex_a8_init_target(struct command_context_s *cmd_ctx,
-               struct target_s *target);
-int cortex_a8_examine(struct target_s *target);
-int cortex_a8_poll(target_t *target);
-int cortex_a8_halt(target_t *target);
-int cortex_a8_resume(struct target_s *target, int current, uint32_t address,
-               int handle_breakpoints, int debug_execution);
-int cortex_a8_step(struct target_s *target, int current, uint32_t address,
-               int handle_breakpoints);
-int cortex_a8_debug_entry(target_t *target);
-int cortex_a8_restore_context(target_t *target);
-int cortex_a8_bulk_write_memory(target_t *target, uint32_t address,
-               uint32_t count, uint8_t *buffer);
-int cortex_a8_set_breakpoint(struct target_s *target,
-               breakpoint_t *breakpoint, uint8_t matchmode);
-int cortex_a8_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
-int cortex_a8_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
-int cortex_a8_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
-int cortex_a8_dap_read_coreregister_u32(target_t *target,
+static int cortex_a8_poll(struct target *target);
+static int cortex_a8_debug_entry(struct target *target);
+static int cortex_a8_restore_context(struct target *target);
+static int cortex_a8_set_breakpoint(struct target *target,
+               struct breakpoint *breakpoint, uint8_t matchmode);
+static int cortex_a8_unset_breakpoint(struct target *target,
+               struct breakpoint *breakpoint);
+static int cortex_a8_dap_read_coreregister_u32(struct target *target,
                uint32_t *value, int regnum);
-int cortex_a8_dap_write_coreregister_u32(target_t *target,
+static int cortex_a8_dap_write_coreregister_u32(struct target *target,
                uint32_t value, int regnum);
-
-target_type_t cortexa8_target =
-{
-       .name = "cortex_a8",
-
-       .poll = cortex_a8_poll,
-       .arch_state = armv7a_arch_state,
-
-       .target_request_data = NULL,
-
-       .halt = cortex_a8_halt,
-       .resume = cortex_a8_resume,
-       .step = cortex_a8_step,
-
-       .assert_reset = NULL,
-       .deassert_reset = NULL,
-       .soft_reset_halt = NULL,
-
-//     .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
-       .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
-
-       .read_memory = cortex_a8_read_memory,
-       .write_memory = cortex_a8_write_memory,
-       .bulk_write_memory = cortex_a8_bulk_write_memory,
-       .checksum_memory = arm7_9_checksum_memory,
-       .blank_check_memory = arm7_9_blank_check_memory,
-
-       .run_algorithm = armv4_5_run_algorithm,
-
-       .add_breakpoint = cortex_a8_add_breakpoint,
-       .remove_breakpoint = cortex_a8_remove_breakpoint,
-       .add_watchpoint = NULL,
-       .remove_watchpoint = NULL,
-
-       .register_commands = cortex_a8_register_commands,
-       .target_create = cortex_a8_target_create,
-       .init_target = cortex_a8_init_target,
-       .examine = cortex_a8_examine,
-       .quit = NULL
-};
-
 /*
  * FIXME do topology discovery using the ROM; don't
  * assume this is an OMAP3.
@@ -119,79 +61,81 @@ target_type_t cortexa8_target =
 /*
  * Cortex-A8 Basic debug access, very low level assumes state is saved
  */
-int cortex_a8_init_debug_access(target_t *target)
+static int cortex_a8_init_debug_access(struct target *target)
 {
-#if 0
-# Unlocking the debug registers for modification
-mww 0x54011FB0 0xC5ACCE55 4
-
-# Clear Sticky Power Down status Bit to enable access to
-# the registers in the Core Power Domain
-mdw 0x54011314
-# Check that it is cleared
-mdw 0x54011314
-# Now we can read Core Debug Registers at offset 0x080
-mdw 0x54011080 4
-# We can also read RAM.
-mdw 0x80000000 32
-
-mdw 0x5401d030
-mdw 0x54011FB8
-
-# Set DBGEN line for hardware debug (OMAP35xx)
-mww 0x5401d030 0x00002000
-
-#Check AUTHSTATUS
-mdw 0x54011FB8
-
-# Instr enable
-mww 0x54011088 0x2000
-mdw 0x54011080 4
-#endif
-       return ERROR_OK;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
+
+       int retval;
+       uint32_t dummy;
+
+       LOG_DEBUG(" ");
+
+       /* Unlocking the debug registers for modification */
+       /* The debugport might be uninitialised so try twice */
+       retval = mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
+       if (retval != ERROR_OK)
+               mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
+       /* Clear Sticky Power Down status Bit in PRSR to enable access to
+          the registers in the Core Power Domain */
+       retval = mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_PRSR, &dummy);
+       /* Enabling of instruction execution in debug mode is done in debug_entry code */
+
+       /* Resync breakpoint registers */
+
+       /* Since this is likley called from init or reset, update targtet state information*/
+       cortex_a8_poll(target);
+
+       return retval;
 }
 
-int cortex_a8_exec_opcode(target_t *target, uint32_t opcode)
+int cortex_a8_exec_opcode(struct target *target, uint32_t opcode)
 {
        uint32_t dscr;
-       int retvalue;
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
+       int retval;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
 
        LOG_DEBUG("exec opcode 0x%08" PRIx32, opcode);
        do
        {
-               retvalue = mem_ap_read_atomic_u32(swjdp,
-                               OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+               retval = mem_ap_read_atomic_u32(swjdp,
+                               armv7a->debug_base + CPUDBG_DSCR, &dscr);
+               if (retval != ERROR_OK)
+               {
+                       LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode);
+                       return retval;
+               }
        }
-       while ((dscr & (1 << 24)) == 0); /* Wait for InstrCompl bit to be set */
+       while ((dscr & (1 << DSCR_INSTR_COMP)) == 0); /* Wait for InstrCompl bit to be set */
 
-       mem_ap_write_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_ITR, opcode);
+       mem_ap_write_u32(swjdp, armv7a->debug_base + CPUDBG_ITR, opcode);
 
        do
        {
-               retvalue = mem_ap_read_atomic_u32(swjdp,
-                               OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+               retval = mem_ap_read_atomic_u32(swjdp,
+                               armv7a->debug_base + CPUDBG_DSCR, &dscr);
+               if (retval != ERROR_OK)
+               {
+                       LOG_ERROR("Could not read DSCR register");
+                       return retval;
+               }
        }
-       while ((dscr & (1 << 24)) == 0); /* Wait for InstrCompl bit to be set */
+       while ((dscr & (1 << DSCR_INSTR_COMP)) == 0); /* Wait for InstrCompl bit to be set */
 
-       return retvalue;
+       return retval;
 }
 
 /**************************************************************************
 Read core register with very few exec_opcode, fast but needs work_area.
 This can cause problems with MMU active.
 **************************************************************************/
-int cortex_a8_read_regs_through_mem(target_t *target, uint32_t address,
+static int cortex_a8_read_regs_through_mem(struct target *target, uint32_t address,
                uint32_t * regfile)
 {
        int retval = ERROR_OK;
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
 
        cortex_a8_dap_read_coreregister_u32(target, regfile, 0);
        cortex_a8_dap_write_coreregister_u32(target, address, 0);
@@ -203,14 +147,12 @@ int cortex_a8_read_regs_through_mem(target_t *target, uint32_t address,
        return retval;
 }
 
-int cortex_a8_read_cp(target_t *target, uint32_t *value, uint8_t CP,
+static int cortex_a8_read_cp(struct target *target, uint32_t *value, uint8_t CP,
                uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
 {
        int retval;
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
 
        cortex_a8_exec_opcode(target, ARMV4_5_MRC(CP, op1, 0, CRn, CRm, op2));
        /* Move R0 to DTRTX */
@@ -218,70 +160,103 @@ int cortex_a8_read_cp(target_t *target, uint32_t *value, uint8_t CP,
 
        /* Read DCCTX */
        retval = mem_ap_read_atomic_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
+                       armv7a->debug_base + CPUDBG_DTRTX, value);
 
        return retval;
 }
 
-int cortex_a8_write_cp(target_t *target, uint32_t value,
+static int cortex_a8_write_cp(struct target *target, uint32_t value,
        uint8_t CP, uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
-/* TODO Fix this */
 {
        int retval;
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
+       uint32_t dscr;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
+
+       LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32, CP, CRn, value);
+
+       /* Check that DCCRX is not full */
+       retval = mem_ap_read_atomic_u32(swjdp,
+                               armv7a->debug_base + CPUDBG_DSCR, &dscr);
+       if (dscr & (1 << DSCR_DTR_RX_FULL))
+       {
+               LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
+               /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode  0xEE000E15 */
+               cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
+       }
 
        retval = mem_ap_write_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_DTRRX, value);
+                       armv7a->debug_base + CPUDBG_DTRRX, value);
        /* Move DTRRX to r0 */
        cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
 
-       cortex_a8_exec_opcode(target, ARMV4_5_MCR(CP, 0, 0, 0, 5, 0));
+       cortex_a8_exec_opcode(target, ARMV4_5_MCR(CP, op1, 0, CRn, CRm, op2));
        return retval;
 }
 
-int cortex_a8_read_cp15(target_t *target, uint32_t op1, uint32_t op2,
+static int cortex_a8_read_cp15(struct target *target, uint32_t op1, uint32_t op2,
                uint32_t CRn, uint32_t CRm, uint32_t *value)
 {
        return cortex_a8_read_cp(target, value, 15, op1, CRn, CRm, op2);
 }
 
-int cortex_a8_write_cp15(target_t *target, uint32_t op1, uint32_t op2,
+static int cortex_a8_write_cp15(struct target *target, uint32_t op1, uint32_t op2,
                uint32_t CRn, uint32_t CRm, uint32_t value)
 {
        return cortex_a8_write_cp(target, value, 15, op1, CRn, CRm, op2);
 }
 
-int cortex_a8_dap_read_coreregister_u32(target_t *target,
+static int cortex_a8_mrc(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
+{
+       if (cpnum!=15)
+       {
+               LOG_ERROR("Only cp15 is supported");
+               return ERROR_FAIL;
+       }
+       return cortex_a8_read_cp15(target, op1, op2, CRn, CRm, value);
+}
+
+static int cortex_a8_mcr(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
+{
+       if (cpnum!=15)
+       {
+               LOG_ERROR("Only cp15 is supported");
+               return ERROR_FAIL;
+       }
+       return cortex_a8_write_cp15(target, op1, op2, CRn, CRm, value);
+}
+
+
+
+static int cortex_a8_dap_read_coreregister_u32(struct target *target,
                uint32_t *value, int regnum)
 {
        int retval = ERROR_OK;
        uint8_t reg = regnum&0xFF;
        uint32_t dscr;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
 
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
-
-       if (reg > 16)
+       if (reg > 17)
                return retval;
 
        if (reg < 15)
        {
-               /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0,  0xEE000E15 */
+               /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0"  0xEE00nE15 */
                cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, reg, 0, 5, 0));
        }
        else if (reg == 15)
        {
+               /* "MOV r0, r15"; then move r0 to DCCTX */
                cortex_a8_exec_opcode(target, 0xE1A0000F);
                cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
        }
-       else if (reg == 16)
+       else
        {
-               cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, 0));
+               /* "MRS r0, CPSR" or "MRS r0, SPSR"
+                * then move r0 to DCCTX
+                */
+               cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, reg & 1));
                cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
        }
 
@@ -289,75 +264,105 @@ int cortex_a8_dap_read_coreregister_u32(target_t *target,
        do
        {
                retval = mem_ap_read_atomic_u32(swjdp,
-                               OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+                               armv7a->debug_base + CPUDBG_DSCR, &dscr);
        }
-       while ((dscr & (1 << 29)) == 0); /* Wait for DTRRXfull */
+       while ((dscr & (1 << DSCR_DTR_TX_FULL)) == 0); /* Wait for DTRRXfull */
 
        retval = mem_ap_read_atomic_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
+                       armv7a->debug_base + CPUDBG_DTRTX, value);
+       LOG_DEBUG("read DCC 0x%08" PRIx32, *value);
 
        return retval;
 }
 
-int cortex_a8_dap_write_coreregister_u32(target_t *target, uint32_t value, int regnum)
+static int cortex_a8_dap_write_coreregister_u32(struct target *target,
+               uint32_t value, int regnum)
 {
        int retval = ERROR_OK;
        uint8_t Rd = regnum&0xFF;
+       uint32_t dscr;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
 
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
+       LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value);
 
-       if (Rd > 16)
+       /* Check that DCCRX is not full */
+       retval = mem_ap_read_atomic_u32(swjdp,
+                               armv7a->debug_base + CPUDBG_DSCR, &dscr);
+       if (dscr & (1 << DSCR_DTR_RX_FULL))
+       {
+               LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
+               /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode  0xEE000E15 */
+               cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
+       }
+
+       if (Rd > 17)
                return retval;
 
        /* Write to DCCRX */
+       LOG_DEBUG("write DCC 0x%08" PRIx32, value);
        retval = mem_ap_write_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_DTRRX, value);
+                       armv7a->debug_base + CPUDBG_DTRRX, value);
 
        if (Rd < 15)
        {
-               /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0,  0xEE000E15 */
+               /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
                cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0));
        }
        else if (Rd == 15)
        {
+               /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
+                * then "mov r15, r0"
+                */
                cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
                cortex_a8_exec_opcode(target, 0xE1A0F000);
        }
-       else if (Rd == 16)
+       else
        {
+               /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
+                * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
+                */
                cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
-               cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, 0));
-               /* Execute a PrefetchFlush instruction through the ITR. */
-               cortex_a8_exec_opcode(target, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
+               cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, Rd & 1));
+
+               /* "Prefetch flush" after modifying execution status in CPSR */
+               if (Rd == 16)
+                       cortex_a8_exec_opcode(target,
+                                       ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
        }
 
        return retval;
 }
 
+/* Write to memory mapped registers directly with no cache or mmu handling */
+static int cortex_a8_dap_write_memap_register_u32(struct target *target, uint32_t address, uint32_t value)
+{
+       int retval;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
+
+       retval = mem_ap_write_atomic_u32(swjdp, address, value);
+
+       return retval;
+}
+
 /*
  * Cortex-A8 Run control
  */
 
-int cortex_a8_poll(target_t *target)
+static int cortex_a8_poll(struct target *target)
 {
        int retval = ERROR_OK;
        uint32_t dscr;
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
-
-
+       struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
+       struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
        enum target_state prev_target_state = target->state;
-
        uint8_t saved_apsel = dap_ap_get_select(swjdp);
+
        dap_ap_select(swjdp, swjdp_debugap);
        retval = mem_ap_read_atomic_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+                       armv7a->debug_base + CPUDBG_DSCR, &dscr);
        if (retval != ERROR_OK)
        {
                dap_ap_select(swjdp, saved_apsel);
@@ -410,38 +415,53 @@ int cortex_a8_poll(target_t *target)
        return retval;
 }
 
-int cortex_a8_halt(target_t *target)
+static int cortex_a8_halt(struct target *target)
 {
        int retval = ERROR_OK;
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
-
+       uint32_t dscr;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
        uint8_t saved_apsel = dap_ap_get_select(swjdp);
        dap_ap_select(swjdp, swjdp_debugap);
 
-       /* Perhaps we should do a read-modify-write here */
+       /*
+        * Tell the core to be halted by writing DRCR with 0x1
+        * and then wait for the core to be halted.
+        */
+       retval = mem_ap_write_atomic_u32(swjdp,
+                       armv7a->debug_base + CPUDBG_DRCR, 0x1);
+
+       /*
+        * enter halting debug mode
+        */
+       mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_DSCR, &dscr);
        retval = mem_ap_write_atomic_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x1);
+               armv7a->debug_base + CPUDBG_DSCR, dscr | (1 << DSCR_HALT_DBG_MODE));
+
+       if (retval != ERROR_OK)
+               goto out;
+
+       do {
+               mem_ap_read_atomic_u32(swjdp,
+                       armv7a->debug_base + CPUDBG_DSCR, &dscr);
+       } while ((dscr & (1 << DSCR_CORE_HALTED)) == 0);
 
        target->debug_reason = DBG_REASON_DBGRQ;
-       dap_ap_select(swjdp, saved_apsel);
 
+out:
+       dap_ap_select(swjdp, saved_apsel);
        return retval;
 }
 
-int cortex_a8_resume(struct target_s *target, int current,
+static int cortex_a8_resume(struct target *target, int current,
                uint32_t address, int handle_breakpoints, int debug_execution)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
 
-//     breakpoint_t *breakpoint = NULL;
-       uint32_t resume_pc;
+//     struct breakpoint *breakpoint = NULL;
+       uint32_t resume_pc, dscr;
 
        uint8_t saved_apsel = dap_ap_get_select(swjdp);
        dap_ap_select(swjdp, swjdp_debugap);
@@ -476,7 +496,7 @@ int cortex_a8_resume(struct target_s *target, int current,
 
        /* current = 1: continue on current pc, otherwise continue at <address> */
        resume_pc = buf_get_u32(
-                       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).value,
                        0, 32);
        if (!current)
@@ -485,17 +505,29 @@ int cortex_a8_resume(struct target_s *target, int current,
        /* Make sure that the Armv7 gdb thumb fixups does not
         * kill the return address
         */
-       if (!(cortex_a8->cpudbg_dscr & (1 << 5)))
+       switch (armv4_5->core_state)
        {
+       case ARMV4_5_STATE_ARM:
                resume_pc &= 0xFFFFFFFC;
+               break;
+       case ARMV4_5_STATE_THUMB:
+       case ARM_STATE_THUMB_EE:
+               /* When the return address is loaded into PC
+                * bit 0 must be 1 to stay in Thumb state
+                */
+               resume_pc |= 0x1;
+               break;
+       case ARMV4_5_STATE_JAZELLE:
+               LOG_ERROR("How do I resume into Jazelle state??");
+               return ERROR_FAIL;
        }
        LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
-       buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).value,
                        0, 32, resume_pc);
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                        armv4_5->core_mode, 15).dirty = 1;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                        armv4_5->core_mode, 15).valid = 1;
 
        cortex_a8_restore_context(target);
@@ -515,15 +547,19 @@ int cortex_a8_resume(struct target_s *target, int current,
        }
 
 #endif
-       /* Restart core */
-       /* Perhaps we should do a read-modify-write here */
-       mem_ap_write_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x2);
+       /* Restart core and wait for it to be started */
+       mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_DRCR, 0x2);
+
+       do {
+               mem_ap_read_atomic_u32(swjdp,
+                       armv7a->debug_base + CPUDBG_DSCR, &dscr);
+       } while ((dscr & (1 << DSCR_CORE_RESTARTED)) == 0);
 
        target->debug_reason = DBG_REASON_NOTHALTED;
        target->state = TARGET_RUNNING;
 
        /* registers are now invalid */
-       armv4_5_invalidate_core_regs(target);
+       register_cache_invalidate(armv4_5->core_cache);
 
        if (!debug_execution)
        {
@@ -543,24 +579,27 @@ int cortex_a8_resume(struct target_s *target, int current,
        return ERROR_OK;
 }
 
-int cortex_a8_debug_entry(target_t *target)
+static int cortex_a8_debug_entry(struct target *target)
 {
        int i;
-       uint32_t regfile[16], pc, cpsr;
+       uint32_t regfile[16], pc, cpsr, dscr;
        int retval = ERROR_OK;
-       working_area_t *regfile_working_area = NULL;
-
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
-
-       if (armv7a->pre_debug_entry)
-               armv7a->pre_debug_entry(target);
+       struct working_area *regfile_working_area = NULL;
+       struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
+       struct reg *reg;
 
        LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr);
 
+       /* Enable the ITR execution once we are in debug mode */
+       mem_ap_read_atomic_u32(swjdp,
+                               armv7a->debug_base + CPUDBG_DSCR, &dscr);
+       dscr |= (1 << DSCR_EXT_INT_EN);
+       retval = mem_ap_write_atomic_u32(swjdp,
+                       armv7a->debug_base + CPUDBG_DSCR, dscr);
+
        /* Examine debug reason */
        switch ((cortex_a8->cpudbg_dscr >> 2)&0xF)
        {
@@ -581,51 +620,77 @@ int cortex_a8_debug_entry(target_t *target)
        }
 
        /* Examine target state and mode */
-       dap_ap_select(swjdp, swjdp_memoryap);
        if (cortex_a8->fast_reg_read)
                target_alloc_working_area(target, 64, &regfile_working_area);
 
        /* First load register acessible through core debug port*/
        if (!regfile_working_area)
        {
+               /* FIXME we don't actually need all these registers;
+                * reading them slows us down.  Just R0, PC, CPSR...
+                */
                for (i = 0; i <= 15; i++)
                        cortex_a8_dap_read_coreregister_u32(target,
                                        &regfile[i], i);
        }
        else
        {
+               dap_ap_select(swjdp, swjdp_memoryap);
                cortex_a8_read_regs_through_mem(target,
                                regfile_working_area->address, regfile);
                dap_ap_select(swjdp, swjdp_memoryap);
                target_free_working_area(target, regfile_working_area);
        }
 
+       /* read Current PSR */
        cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16);
        pc = regfile[15];
        dap_ap_select(swjdp, swjdp_debugap);
        LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr);
 
-       armv4_5->core_mode = cpsr & 0x3F;
+       armv4_5->core_mode = cpsr & 0x1F;
+
+       i = (cpsr >> 5) & 1;    /* T */
+       i |= (cpsr >> 23) & 1;  /* J << 1 */
+       switch (i) {
+       case 0: /* J = 0, T = 0 */
+               armv4_5->core_state = ARMV4_5_STATE_ARM;
+               break;
+       case 1: /* J = 0, T = 1 */
+               armv4_5->core_state = ARMV4_5_STATE_THUMB;
+               break;
+       case 2: /* J = 1, T = 0 */
+               LOG_WARNING("Jazelle state -- not handled");
+               armv4_5->core_state = ARMV4_5_STATE_JAZELLE;
+               break;
+       case 3: /* J = 1, T = 1 */
+               /* ThumbEE is very much like Thumb, but some of the
+                * instructions are different.  Single stepping and
+                * breakpoints need updating...
+                */
+               LOG_WARNING("ThumbEE -- incomplete support");
+               armv4_5->core_state = ARM_STATE_THUMB_EE;
+               break;
+       }
+
+       /* update cache */
+       reg = armv4_5->core_cache->reg_list + ARMV4_5_CPSR;
+       buf_set_u32(reg->value, 0, 32, cpsr);
+       reg->valid = 1;
+       reg->dirty = 0;
 
        for (i = 0; i <= ARM_PC; i++)
        {
-               buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
-                                       armv4_5->core_mode, i).value,
-                               0, 32, regfile[i]);
-               ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
-                               armv4_5->core_mode, i).valid = 1;
-               ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
-                               armv4_5->core_mode, i).dirty = 0;
-       }
-       buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
-                               armv4_5->core_mode, 16).value,
-                       0, 32, cpsr);
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
+               reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+                                       armv4_5->core_mode, i);
+
+               buf_set_u32(reg->value, 0, 32, regfile[i]);
+               reg->valid = 1;
+               reg->dirty = 0;
+       }
 
        /* Fixup PC Resume Address */
-       /* TODO Her we should use arch->core_state */
-       if (cortex_a8->cpudbg_dscr & (1 << 5))
+       if (cpsr & (1 << 5))
        {
                // T bit set for Thumb or ThumbEE state
                regfile[ARM_PC] -= 4;
@@ -635,15 +700,15 @@ int cortex_a8_debug_entry(target_t *target)
                // ARM state
                regfile[ARM_PC] -= 8;
        }
-       buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, ARM_PC).value,
                        0, 32, regfile[ARM_PC]);
 
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
-               .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
+               .dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 0).valid;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
-               .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
+               .dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).valid;
 
 #if 0
@@ -670,12 +735,10 @@ int cortex_a8_debug_entry(target_t *target)
 
 }
 
-void cortex_a8_post_debug_entry(target_t *target)
+static void cortex_a8_post_debug_entry(struct target *target)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
+       struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
+       struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
 
 //     cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
        /* examine cp15 control reg */
@@ -704,15 +767,13 @@ void cortex_a8_post_debug_entry(target_t *target)
 
 }
 
-int cortex_a8_step(struct target_s *target, int current, uint32_t address,
+static int cortex_a8_step(struct target *target, int current, uint32_t address,
                int handle_breakpoints)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
-       breakpoint_t *breakpoint = NULL;
-       breakpoint_t stepbreakpoint;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
+       struct breakpoint *breakpoint = NULL;
+       struct breakpoint stepbreakpoint;
 
        int timeout = 100;
 
@@ -725,13 +786,13 @@ int cortex_a8_step(struct target_s *target, int current, uint32_t address,
        /* current = 1: continue on current pc, otherwise continue at <address> */
        if (!current)
        {
-               buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, ARM_PC).value,
                                0, 32, address);
        }
        else
        {
-               address = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               address = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, ARM_PC).value,
                                0, 32);
        }
@@ -743,7 +804,8 @@ int cortex_a8_step(struct target_s *target, int current, uint32_t address,
        handle_breakpoints = 1;
        if (handle_breakpoints) {
                breakpoint = breakpoint_find(target,
-                               buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                               buf_get_u32(ARMV4_5_CORE_REG_MODE(
+                                       armv4_5->core_cache,
                                        armv4_5->core_mode, 15).value,
                        0, 32));
                if (breakpoint)
@@ -752,7 +814,8 @@ int cortex_a8_step(struct target_s *target, int current, uint32_t address,
 
        /* Setup single step breakpoint */
        stepbreakpoint.address = address;
-       stepbreakpoint.length = (cortex_a8->cpudbg_dscr & (1 << 5)) ? 2 : 4;
+       stepbreakpoint.length = (armv4_5->core_state == ARMV4_5_STATE_THUMB)
+                       ? 2 : 4;
        stepbreakpoint.type = BKPT_HARD;
        stepbreakpoint.set = 0;
 
@@ -785,14 +848,12 @@ int cortex_a8_step(struct target_s *target, int current, uint32_t address,
        return ERROR_OK;
 }
 
-int cortex_a8_restore_context(target_t *target)
+static int cortex_a8_restore_context(struct target *target)
 {
        int i;
        uint32_t value;
-
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
 
        LOG_DEBUG(" ");
 
@@ -801,10 +862,11 @@ int cortex_a8_restore_context(target_t *target)
 
        for (i = 15; i >= 0; i--)
        {
-               if (ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, i).dirty)
                {
-                       value = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       value = buf_get_u32(ARMV4_5_CORE_REG_MODE(
+                                               armv4_5->core_cache,
                                                armv4_5->core_mode, i).value,
                                        0, 32);
                        /* TODO Check return values */
@@ -819,16 +881,15 @@ int cortex_a8_restore_context(target_t *target)
 }
 
 
+#if 0
 /*
  * Cortex-A8 Core register functions
  */
-
-int cortex_a8_load_core_reg_u32(struct target_s *target, int num,
+static int cortex_a8_load_core_reg_u32(struct target *target, int num,
                armv4_5_mode_t mode, uint32_t * value)
 {
        int retval;
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
        if ((num <= ARM_CPSR))
        {
@@ -849,26 +910,24 @@ int cortex_a8_load_core_reg_u32(struct target_s *target, int num,
 
        /* Register other than r0 - r14 uses r0 for access */
        if (num > 14)
-               ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 0).dirty =
-                       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 0).valid;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).dirty =
-                       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                armv4_5->core_mode, 15).valid;
 
        return ERROR_OK;
 }
 
-int cortex_a8_store_core_reg_u32(struct target_s *target, int num,
+static int cortex_a8_store_core_reg_u32(struct target *target, int num,
                armv4_5_mode_t mode, uint32_t value)
 {
        int retval;
 //     uint32_t reg;
-
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
 #ifdef ARMV7_GDB_HACKS
        /* If the LR register is being modified, make sure it will put us
@@ -887,9 +946,9 @@ int cortex_a8_store_core_reg_u32(struct target_s *target, int num,
                if (retval != ERROR_OK)
                {
                        LOG_ERROR("JTAG failure %i", retval);
-                       ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, num).dirty =
-                               ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
+                               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
                                        armv4_5->core_mode, num).valid;
                        return ERROR_JTAG_DEVICE_ERROR;
                }
@@ -902,45 +961,123 @@ int cortex_a8_store_core_reg_u32(struct target_s *target, int num,
 
        return ERROR_OK;
 }
+#endif
+
 
+static int cortex_a8_write_core_reg(struct target *target, int num,
+               enum armv4_5_mode mode, uint32_t value);
 
-int cortex_a8_read_core_reg(struct target_s *target, int num,
+static int cortex_a8_read_core_reg(struct target *target, int num,
                enum armv4_5_mode mode)
 {
        uint32_t value;
        int retval;
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       cortex_a8_dap_read_coreregister_u32(target, &value, num);
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
+       struct reg_cache *cache = armv4_5->core_cache;
+       uint32_t cpsr = 0;
+       unsigned cookie = num;
 
-       if ((retval = jtag_execute_queue()) != ERROR_OK)
-       {
-               return retval;
+       /* avoid some needless mode changes
+        * FIXME move some of these to shared ARM code...
+        */
+       if (mode != armv4_5->core_mode) {
+               if ((armv4_5->core_mode == ARMV4_5_MODE_SYS)
+                               && (mode == ARMV4_5_MODE_USR))
+                       mode = ARMV4_5_MODE_ANY;
+               else if ((mode != ARMV4_5_MODE_FIQ) && (num <= 12))
+                       mode = ARMV4_5_MODE_ANY;
+
+               if (mode != ARMV4_5_MODE_ANY) {
+                       cpsr = buf_get_u32(cache ->reg_list[ARMV4_5_CPSR]
+                                       .value, 0, 32);
+                       cortex_a8_write_core_reg(target, 16,
+                                       ARMV4_5_MODE_ANY, mode);
+               }
        }
 
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
-       buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
-                       mode, num).value, 0, 32, value);
+       if (num == 16) {
+               switch (mode) {
+               case ARMV4_5_MODE_USR:
+               case ARMV4_5_MODE_SYS:
+               case ARMV4_5_MODE_ANY:
+                       /* CPSR */
+                       break;
+               default:
+                       /* SPSR */
+                       cookie++;
+                       break;
+               }
+       }
 
-       return ERROR_OK;
+       cortex_a8_dap_read_coreregister_u32(target, &value, cookie);
+       retval = jtag_execute_queue();
+       if (retval == ERROR_OK) {
+               struct reg *r = &ARMV4_5_CORE_REG_MODE(cache, mode, num);
+
+               r->valid = 1;
+               r->dirty = 0;
+               buf_set_u32(r->value, 0, 32, value);
+       }
+
+       if (cpsr)
+               cortex_a8_write_core_reg(target, 16, ARMV4_5_MODE_ANY, cpsr);
+       return retval;
 }
 
-int cortex_a8_write_core_reg(struct target_s *target, int num,
+static int cortex_a8_write_core_reg(struct target *target, int num,
                enum armv4_5_mode mode, uint32_t value)
 {
        int retval;
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
+       struct reg_cache *cache = armv4_5->core_cache;
+       uint32_t cpsr = 0;
+       unsigned cookie = num;
 
-       cortex_a8_dap_write_coreregister_u32(target, value, num);
-       if ((retval = jtag_execute_queue()) != ERROR_OK)
-       {
-               return retval;
+       /* avoid some needless mode changes
+        * FIXME move some of these to shared ARM code...
+        */
+       if (mode != armv4_5->core_mode) {
+               if ((armv4_5->core_mode == ARMV4_5_MODE_SYS)
+                               && (mode == ARMV4_5_MODE_USR))
+                       mode = ARMV4_5_MODE_ANY;
+               else if ((mode != ARMV4_5_MODE_FIQ) && (num <= 12))
+                       mode = ARMV4_5_MODE_ANY;
+
+               if (mode != ARMV4_5_MODE_ANY) {
+                       cpsr = buf_get_u32(cache ->reg_list[ARMV4_5_CPSR]
+                                       .value, 0, 32);
+                       cortex_a8_write_core_reg(target, 16,
+                                       ARMV4_5_MODE_ANY, mode);
+               }
        }
 
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
-       ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
 
-       return ERROR_OK;
+       if (num == 16) {
+               switch (mode) {
+               case ARMV4_5_MODE_USR:
+               case ARMV4_5_MODE_SYS:
+               case ARMV4_5_MODE_ANY:
+                       /* CPSR */
+                       break;
+               default:
+                       /* SPSR */
+                       cookie++;
+                       break;
+               }
+       }
+
+       cortex_a8_dap_write_coreregister_u32(target, value, cookie);
+       if ((retval = jtag_execute_queue()) == ERROR_OK) {
+               struct reg *r = &ARMV4_5_CORE_REG_MODE(cache, mode, num);
+
+               buf_set_u32(r->value, 0, 32, value);
+               r->valid = 1;
+               r->dirty = 0;
+       }
+
+       if (cpsr)
+               cortex_a8_write_core_reg(target, 16, ARMV4_5_MODE_ANY, cpsr);
+       return retval;
 }
 
 
@@ -949,20 +1086,16 @@ int cortex_a8_write_core_reg(struct target_s *target, int num,
  */
 
 /* Setup hardware Breakpoint Register Pair */
-int cortex_a8_set_breakpoint(struct target_s *target,
-               breakpoint_t *breakpoint, uint8_t matchmode)
+static int cortex_a8_set_breakpoint(struct target *target,
+               struct breakpoint *breakpoint, uint8_t matchmode)
 {
        int retval;
        int brp_i=0;
        uint32_t control;
        uint8_t byte_addr_select = 0x0F;
-
-
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
-       cortex_a8_brp_t * brp_list = cortex_a8->brp_list;
+       struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
+       struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
+       struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
 
        if (breakpoint->set)
        {
@@ -977,7 +1110,7 @@ int cortex_a8_set_breakpoint(struct target_s *target,
                if (brp_i >= cortex_a8->brp_num)
                {
                        LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
-                       exit(-1);
+                       return ERROR_FAIL;
                }
                breakpoint->set = brp_i + 1;
                if (breakpoint->length == 2)
@@ -990,10 +1123,10 @@ int cortex_a8_set_breakpoint(struct target_s *target,
                brp_list[brp_i].used = 1;
                brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
                brp_list[brp_i].control = control;
-               target_write_u32(target, OMAP3530_DEBUG_BASE
+               cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
                                + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
                                brp_list[brp_i].value);
-               target_write_u32(target, OMAP3530_DEBUG_BASE
+               cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
                                + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
                                brp_list[brp_i].control);
                LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
@@ -1028,14 +1161,12 @@ int cortex_a8_set_breakpoint(struct target_s *target,
        return ERROR_OK;
 }
 
-int cortex_a8_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
+static int cortex_a8_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
 {
        int retval;
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
-       cortex_a8_brp_t * brp_list = cortex_a8->brp_list;
+       struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
+       struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
+       struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
 
        if (!breakpoint->set)
        {
@@ -1056,10 +1187,10 @@ int cortex_a8_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint
                brp_list[brp_i].used = 0;
                brp_list[brp_i].value = 0;
                brp_list[brp_i].control = 0;
-               target_write_u32(target, OMAP3530_DEBUG_BASE
+               cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
                                + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
                                brp_list[brp_i].control);
-               target_write_u32(target, OMAP3530_DEBUG_BASE
+               cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
                                + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
                                brp_list[brp_i].value);
        }
@@ -1088,12 +1219,9 @@ int cortex_a8_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint
        return ERROR_OK;
 }
 
-int cortex_a8_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
+int cortex_a8_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
+       struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
 
        if ((breakpoint->type == BKPT_HARD) && (cortex_a8->brp_num_available < 1))
        {
@@ -1108,12 +1236,9 @@ int cortex_a8_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
        return ERROR_OK;
 }
 
-int cortex_a8_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
+static int cortex_a8_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
+       struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
 
 #if 0
 /* It is perfectly possible to remove brakpoints while the taget is running */
@@ -1141,6 +1266,34 @@ int cortex_a8_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoin
  * Cortex-A8 Reset fuctions
  */
 
+static int cortex_a8_assert_reset(struct target *target)
+{
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+
+       LOG_DEBUG(" ");
+
+       /* registers are now invalid */
+       register_cache_invalidate(armv7a->armv4_5_common.core_cache);
+
+       target->state = TARGET_RESET;
+
+       return ERROR_OK;
+}
+
+static int cortex_a8_deassert_reset(struct target *target)
+{
+
+       LOG_DEBUG(" ");
+
+       if (target->reset_halt)
+       {
+               int retval;
+               if ((retval = target_halt(target)) != ERROR_OK)
+                       return retval;
+       }
+
+       return ERROR_OK;
+}
 
 /*
  * Cortex-A8 Memory access
@@ -1149,26 +1302,19 @@ int cortex_a8_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoin
  * ap number for every access.
  */
 
-int cortex_a8_read_memory(struct target_s *target, uint32_t address,
+static int cortex_a8_read_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
-
-       int retval = ERROR_OK;
-
-       /* sanitize arguments */
-       if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
-               return ERROR_INVALID_ARGUMENTS;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
+       int retval = ERROR_INVALID_ARGUMENTS;
 
        /* cortex_a8 handles unaligned memory access */
 
 // ??? dap_ap_select(swjdp, swjdp_memoryap);
 
-       switch (size)
-       {
+       if (count && buffer) {
+               switch (size) {
                case 4:
                        retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
                        break;
@@ -1178,32 +1324,23 @@ int cortex_a8_read_memory(struct target_s *target, uint32_t address,
                case 1:
                        retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
                        break;
-               default:
-                       LOG_ERROR("BUG: we shouldn't get here");
-                       exit(-1);
+               }
        }
 
        return retval;
 }
 
-int cortex_a8_write_memory(struct target_s *target, uint32_t address,
+int cortex_a8_write_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
-
-       int retval;
-
-       /* sanitize arguments */
-       if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
-               return ERROR_INVALID_ARGUMENTS;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
+       int retval = ERROR_INVALID_ARGUMENTS;
 
 // ??? dap_ap_select(swjdp, swjdp_memoryap);
 
-       switch (size)
-       {
+       if (count && buffer) {
+               switch (size) {
                case 4:
                        retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
                        break;
@@ -1213,22 +1350,41 @@ int cortex_a8_write_memory(struct target_s *target, uint32_t address,
                case 1:
                        retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
                        break;
-               default:
-                       LOG_ERROR("BUG: we shouldn't get here");
-                       exit(-1);
+               }
+       }
+
+       if (retval == ERROR_OK && target->state == TARGET_HALTED)
+       {
+               /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
+               /* invalidate I-Cache */
+               if (armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
+               {
+                       /* Invalidate ICache single entry with MVA, repeat this for all cache
+                          lines in the address range, Cortex-A8 has fixed 64 byte line length */
+                       /* Invalidate Cache single entry with MVA to PoU */
+                       for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
+                               armv7a->write_cp15(target, 0, 1, 7, 5, cacheline); /* I-Cache to PoU */
+               }
+               /* invalidate D-Cache */
+               if (armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
+               {
+                       /* Invalidate Cache single entry with MVA to PoC */
+                       for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
+                               armv7a->write_cp15(target, 0, 1, 7, 6, cacheline); /* U/D cache to PoC */
+               }
        }
 
        return retval;
 }
 
-int cortex_a8_bulk_write_memory(target_t *target, uint32_t address,
+static int cortex_a8_bulk_write_memory(struct target *target, uint32_t address,
                uint32_t count, uint8_t *buffer)
 {
        return cortex_a8_write_memory(target, address, 4, count, buffer);
 }
 
 
-int cortex_a8_dcc_read(swjdp_common_t *swjdp, uint8_t *value, uint8_t *ctrl)
+static int cortex_a8_dcc_read(struct swjdp_common *swjdp, uint8_t *value, uint8_t *ctrl)
 {
 #if 0
        u16 dcrdr;
@@ -1251,16 +1407,14 @@ int cortex_a8_dcc_read(swjdp_common_t *swjdp, uint8_t *value, uint8_t *ctrl)
 }
 
 
-int cortex_a8_handle_target_request(void *priv)
+static int cortex_a8_handle_target_request(void *priv)
 {
-       target_t *target = priv;
-       if (!target->type->examined)
-               return ERROR_OK;
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
-
+       struct target *target = priv;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
 
+       if (!target_was_examined(target))
+               return ERROR_OK;
        if (!target->dbg_msg_enabled)
                return ERROR_OK;
 
@@ -1295,49 +1449,48 @@ int cortex_a8_handle_target_request(void *priv)
  * Cortex-A8 target information and configuration
  */
 
-int cortex_a8_examine(struct target_s *target)
+static int cortex_a8_examine_first(struct target *target)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
-       cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
-
-
+       struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
+       struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
        int i;
        int retval = ERROR_OK;
        uint32_t didr, ctypr, ttypr, cpuid;
 
        LOG_DEBUG("TODO");
 
+       /* Here we shall insert a proper ROM Table scan */
+       armv7a->debug_base = OMAP3530_DEBUG_BASE;
+
        /* We do one extra read to ensure DAP is configured,
         * we call ahbap_debugport_init(swjdp) instead
         */
        ahbap_debugport_init(swjdp);
-       mem_ap_read_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid);
+       mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_CPUID, &cpuid);
        if ((retval = mem_ap_read_atomic_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
+                       armv7a->debug_base + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
        {
                LOG_DEBUG("Examine failed");
                return retval;
        }
 
        if ((retval = mem_ap_read_atomic_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
+                       armv7a->debug_base + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
        {
                LOG_DEBUG("Examine failed");
                return retval;
        }
 
        if ((retval = mem_ap_read_atomic_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
+                       armv7a->debug_base + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
        {
                LOG_DEBUG("Examine failed");
                return retval;
        }
 
        if ((retval = mem_ap_read_atomic_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_DIDR, &didr)) != ERROR_OK)
+                       armv7a->debug_base + CPUDBG_DIDR, &didr)) != ERROR_OK)
        {
                LOG_DEBUG("Examine failed");
                return retval;
@@ -1352,7 +1505,7 @@ int cortex_a8_examine(struct target_s *target)
        cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
        cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
        cortex_a8->brp_num_available = cortex_a8->brp_num;
-       cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(cortex_a8_brp_t));
+       cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(struct cortex_a8_brp));
 //     cortex_a8->brb_enabled = ????;
        for (i = 0; i < cortex_a8->brp_num; i++)
        {
@@ -1369,7 +1522,7 @@ int cortex_a8_examine(struct target_s *target)
        /* Setup Watchpoint Register Pairs */
        cortex_a8->wrp_num = ((didr >> 28) & 0x0F) + 1;
        cortex_a8->wrp_num_available = cortex_a8->wrp_num;
-       cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(cortex_a8_wrp_t));
+       cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(struct cortex_a8_wrp));
        for (i = 0; i < cortex_a8->wrp_num; i++)
        {
                cortex_a8->wrp_list[i].used = 0;
@@ -1381,7 +1534,21 @@ int cortex_a8_examine(struct target_s *target)
        LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
                        cortex_a8->brp_num , cortex_a8->wrp_num);
 
-       target->type->examined = 1;
+       target_set_examined(target);
+       return ERROR_OK;
+}
+
+static int cortex_a8_examine(struct target *target)
+{
+       int retval = ERROR_OK;
+
+       /* don't re-probe hardware after each reset */
+       if (!target_was_examined(target))
+               retval = cortex_a8_examine_first(target);
+
+       /* Configure core debug access */
+       if (retval == ERROR_OK)
+               retval = cortex_a8_init_debug_access(target);
 
        return retval;
 }
@@ -1390,42 +1557,36 @@ int cortex_a8_examine(struct target_s *target)
  *     Cortex-A8 target creation and initialization
  */
 
-void cortex_a8_build_reg_cache(target_t *target)
+static void cortex_a8_build_reg_cache(struct target *target)
 {
-       reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
+
+       armv4_5->core_type = ARM_MODE_MON;
 
        (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
        armv4_5->core_cache = (*cache_p);
 }
 
 
-int cortex_a8_init_target(struct command_context_s *cmd_ctx,
-               struct target_s *target)
+static int cortex_a8_init_target(struct command_context *cmd_ctx,
+               struct target *target)
 {
        cortex_a8_build_reg_cache(target);
        return ERROR_OK;
 }
 
-int cortex_a8_init_arch_info(target_t *target,
-               cortex_a8_common_t *cortex_a8, jtag_tap_t *tap)
+int cortex_a8_init_arch_info(struct target *target,
+               struct cortex_a8_common *cortex_a8, struct jtag_tap *tap)
 {
-       armv4_5_common_t *armv4_5;
-       armv7a_common_t *armv7a;
-
-       armv7a = &cortex_a8->armv7a_common;
-       armv4_5 = &armv7a->armv4_5_common;
-       swjdp_common_t *swjdp = &armv7a->swjdp_info;
+       struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
+       struct arm *armv4_5 = &armv7a->armv4_5_common;
+       struct swjdp_common *swjdp = &armv7a->swjdp_info;
 
-       /* Setup cortex_a8_common_t */
+       /* Setup struct cortex_a8_common */
        cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
-       cortex_a8->arch_info = NULL;
-       armv7a->arch_info = cortex_a8;
        armv4_5->arch_info = armv7a;
 
-       armv4_5_init_arch_info(target, armv4_5);
-
        /* prepare JTAG information for the new target */
        cortex_a8->jtag_info.tap = tap;
        cortex_a8->jtag_info.scann_size = 4;
@@ -1445,7 +1606,6 @@ LOG_DEBUG(" ");
        /* register arch-specific functions */
        armv7a->examine_debug_reason = NULL;
 
-       armv7a->pre_debug_entry = NULL;
        armv7a->post_debug_entry = cortex_a8_post_debug_entry;
 
        armv7a->pre_restore_context = NULL;
@@ -1466,42 +1626,48 @@ LOG_DEBUG(" ");
 
        armv4_5->read_core_reg = cortex_a8_read_core_reg;
        armv4_5->write_core_reg = cortex_a8_write_core_reg;
-//     armv4_5->full_context = arm7_9_full_context;
 
-//     armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
-//     armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
-//     armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
-//     armv4_5->write_core_reg = armv4_5_write_core_reg;
+       /* REVISIT v7a setup should be in a v7a-specific routine */
+       armv4_5_init_arch_info(target, armv4_5);
+       armv7a->common_magic = ARMV7_COMMON_MAGIC;
 
        target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
 
        return ERROR_OK;
 }
 
-int cortex_a8_target_create(struct target_s *target, Jim_Interp *interp)
+static int cortex_a8_target_create(struct target *target, Jim_Interp *interp)
 {
-       cortex_a8_common_t *cortex_a8 = calloc(1, sizeof(cortex_a8_common_t));
+       struct cortex_a8_common *cortex_a8 = calloc(1, sizeof(struct cortex_a8_common));
 
        cortex_a8_init_arch_info(target, cortex_a8, target->tap);
 
        return ERROR_OK;
 }
 
-static int cortex_a8_handle_cache_info_command(struct command_context_s *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(cortex_a8_handle_cache_info_command)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       armv7a_common_t *armv7a = armv4_5->arch_info;
+       struct target *target = get_current_target(CMD_CTX);
+       struct armv7a_common *armv7a = target_to_armv7a(target);
 
-       return armv4_5_handle_cache_info_command(cmd_ctx,
+       return armv4_5_handle_cache_info_command(CMD_CTX,
                        &armv7a->armv4_5_mmu.armv4_5_cache);
 }
 
 
-int cortex_a8_register_commands(struct command_context_s *cmd_ctx)
+COMMAND_HANDLER(cortex_a8_handle_dbginit_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+
+       cortex_a8_init_debug_access(target);
+
+       return ERROR_OK;
+}
+
+
+static int cortex_a8_register_commands(struct command_context *cmd_ctx)
 {
-       command_t *cortex_a8_cmd;
+       struct command *cortex_a8_cmd;
        int retval = ERROR_OK;
 
        armv4_5_register_commands(cmd_ctx);
@@ -1515,5 +1681,49 @@ int cortex_a8_register_commands(struct command_context_s *cmd_ctx)
                        cortex_a8_handle_cache_info_command, COMMAND_EXEC,
                        "display information about target caches");
 
+       register_command(cmd_ctx, cortex_a8_cmd, "dbginit",
+                       cortex_a8_handle_dbginit_command, COMMAND_EXEC,
+                       "Initialize core debug");
+
        return retval;
 }
+
+struct target_type cortexa8_target = {
+       .name = "cortex_a8",
+
+       .poll = cortex_a8_poll,
+       .arch_state = armv7a_arch_state,
+
+       .target_request_data = NULL,
+
+       .halt = cortex_a8_halt,
+       .resume = cortex_a8_resume,
+       .step = cortex_a8_step,
+
+       .assert_reset = cortex_a8_assert_reset,
+       .deassert_reset = cortex_a8_deassert_reset,
+       .soft_reset_halt = NULL,
+
+       .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
+
+       .read_memory = cortex_a8_read_memory,
+       .write_memory = cortex_a8_write_memory,
+       .bulk_write_memory = cortex_a8_bulk_write_memory,
+
+       .checksum_memory = arm_checksum_memory,
+       .blank_check_memory = arm_blank_check_memory,
+
+       .run_algorithm = armv4_5_run_algorithm,
+
+       .add_breakpoint = cortex_a8_add_breakpoint,
+       .remove_breakpoint = cortex_a8_remove_breakpoint,
+       .add_watchpoint = NULL,
+       .remove_watchpoint = NULL,
+
+       .register_commands = cortex_a8_register_commands,
+       .target_create = cortex_a8_target_create,
+       .init_target = cortex_a8_init_target,
+       .examine = cortex_a8_examine,
+       .mrc = cortex_a8_mrc,
+       .mcr = cortex_a8_mcr,
+};