PIC32: add software reset support
authorSpencer Oliver <ntfreak@users.sourceforge.net>
Tue, 16 Mar 2010 12:54:08 +0000 (12:54 +0000)
committerSpencer Oliver <ntfreak@users.sourceforge.net>
Wed, 17 Mar 2010 09:01:47 +0000 (09:01 +0000)
The PIC32MX does not support the ejtag software reset - it is
optional in the ejtag spec.

We perform the equivalent using the microchip specific MTAP cmd's.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
src/target/mips_ejtag.c
src/target/mips_ejtag.h
src/target/mips_m4k.c
src/target/mips_m4k.h

index 984b535..cea8fa8 100644 (file)
@@ -127,6 +127,37 @@ int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)
        return ERROR_OK;
 }
 
+int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data)
+{
+       struct jtag_tap *tap;
+       tap  = ejtag_info->tap;
+
+       if (tap == NULL)
+               return ERROR_FAIL;
+       struct scan_field field;
+       uint8_t t[4], r[4];
+       int retval;
+
+       field.num_bits = 8;
+       field.out_value = t;
+       buf_set_u32(field.out_value, 0, field.num_bits, *data);
+       field.in_value = r;
+
+       jtag_add_dr_scan(tap, 1, &field, jtag_get_end_state());
+
+       if ((retval = jtag_execute_queue()) != ERROR_OK)
+       {
+               LOG_ERROR("register read failed");
+               return retval;
+       }
+
+       *data = buf_get_u32(field.in_value, 0, 32);
+
+       keep_alive();
+
+       return ERROR_OK;
+}
+
 int mips_ejtag_step_enable(struct mips_ejtag *ejtag_info)
 {
        static const uint32_t code[] = {
index 5c1f245..a086cd5 100644 (file)
 /* microchip PIC32MX specific instructions */
 #define MTAP_SW_MTAP                   0x04
 #define MTAP_SW_ETAP                   0x05
+#define MTAP_COMMAND                   0x07
+
+/* microchip specific cmds */
+#define MCHP_ASERT_RST                 0xd1
+#define MCHP_DE_ASSERT_RST             0xd0
 
 /* ejtag control register bits ECR */
 #define EJTAG_CTRL_TOF                 (1 << 1)
@@ -130,6 +135,7 @@ int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info);
 int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info, uint32_t *impcode);
 int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info, uint32_t *idcode);
 int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data);
+int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data);
 int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write, uint32_t *data);
 
 int mips_ejtag_init(struct mips_ejtag *ejtag_info);
index d3536d8..d1b4589 100644 (file)
@@ -250,11 +250,30 @@ int mips_m4k_assert_reset(struct target *target)
        }
        else
        {
+               if (mips_m4k->is_pic32mx)
+               {
+                       uint32_t mchip_cmd;
+
+                       LOG_DEBUG("Using MTAP reset to reset processor...");
+
+                       /* use microchip specific MTAP reset */
+                       mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP, NULL);
+                       mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND, NULL);
+
+                       mchip_cmd = MCHP_ASERT_RST;
+                       mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
+                       mchip_cmd = MCHP_DE_ASSERT_RST;
+                       mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
+                       mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP, NULL);
+               }
+               else
+               {
                        /* use ejtag reset - not supported by all cores */
                        uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
                        LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
                        mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
                        mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+               }
        }
 
        target->state = TARGET_RESET;
@@ -878,7 +897,7 @@ int mips_m4k_init_target(struct command_context *cmd_ctx, struct target *target)
 int mips_m4k_init_arch_info(struct target *target, struct mips_m4k_common *mips_m4k,
                struct jtag_tap *tap)
 {
-       struct mips32_common *mips32 = &mips_m4k->mips32_common;
+       struct mips32_common *mips32 = &mips_m4k->mips32;
 
        mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
 
@@ -901,8 +920,8 @@ int mips_m4k_target_create(struct target *target, Jim_Interp *interp)
 int mips_m4k_examine(struct target *target)
 {
        int retval;
-       struct mips32_common *mips32 = target_to_mips32(target);
-       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+       struct mips_m4k_common *mips_m4k = target_to_m4k(target);
+       struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
        uint32_t idcode = 0;
 
        if (!target_was_examined(target))
@@ -916,6 +935,7 @@ int mips_m4k_examine(struct target *target)
                         * as it is not selected by default */
                        mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP, NULL);
                        LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
+                       mips_m4k->is_pic32mx = true;
                }
        }
 
index 9b33020..5eb2029 100644 (file)
@@ -32,6 +32,7 @@ struct target;
 struct mips_m4k_common
 {
        int common_magic;
+       bool is_pic32mx;
        struct mips32_common mips32;
 };