cortex_a/r/m: fix handling of un-examined cores
[fw/openocd] / src / target / cortex_a.c
index a97e594e4d4d8e94722ed7d9b53e3ed1545dc39b..256edbca3052eede503670e5858af8212c6bd6b9 100644 (file)
@@ -18,7 +18,7 @@
  *   michel.jaouen@stericsson.com : smp minimum support                    *
  *                                                                         *
  *   Copyright (C) Broadcom 2012                                           *
- *   ehunter@broadcom.com : Cortex R4 support                              *
+ *   ehunter@broadcom.com : Cortex-R4 support                              *
  *                                                                         *
  *   Copyright (C) 2013 Kamal Dasu                                         *
  *   kdasu.kdev@gmail.com                                                  *
@@ -34,9 +34,7 @@
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  *                                                                         *
  *   Cortex-A8(tm) TRM, ARM DDI 0344H                                      *
  *   Cortex-A9(tm) TRM, ARM DDI 0407F                                      *
@@ -55,6 +53,7 @@
 #include "target_request.h"
 #include "target_type.h"
 #include "arm_opcodes.h"
+#include "arm_semihosting.h"
 #include <helper/time_support.h>
 
 static int cortex_a_poll(struct target *target);
@@ -854,7 +853,8 @@ static int cortex_a_halt_smp(struct target *target)
        head = target->head;
        while (head != (struct target_list *)NULL) {
                curr = head->target;
-               if ((curr != target) && (curr->state != TARGET_HALTED))
+               if ((curr != target) && (curr->state != TARGET_HALTED)
+                       && target_was_examined(curr))
                        retval += cortex_a_halt(curr);
                head = head->next;
        }
@@ -917,6 +917,10 @@ static int cortex_a_poll(struct target *target)
                                        if (retval != ERROR_OK)
                                                return retval;
                                }
+
+                               if (arm_semihosting(target, &retval) != 0)
+                                       return retval;
+
                                target_call_event_callbacks(target,
                                        TARGET_EVENT_HALTED);
                        }
@@ -1153,7 +1157,8 @@ static int cortex_a_restore_smp(struct target *target, int handle_breakpoints)
        head = target->head;
        while (head != (struct target_list *)NULL) {
                curr = head->target;
-               if ((curr != target) && (curr->state != TARGET_RUNNING)) {
+               if ((curr != target) && (curr->state != TARGET_RUNNING)
+                       && target_was_examined(curr)) {
                        /*  resume current address , not in step mode */
                        retval += cortex_a_internal_restore(curr, 1, &address,
                                        handle_breakpoints, 0);
@@ -1203,7 +1208,7 @@ static int cortex_a_resume(struct target *target, int current,
 static int cortex_a_debug_entry(struct target *target)
 {
        int i;
-       uint32_t regfile[16], cpsr, dscr;
+       uint32_t regfile[16], cpsr, spsr, dscr;
        int retval = ERROR_OK;
        struct working_area *regfile_working_area = NULL;
        struct cortex_a_common *cortex_a = target_to_cortex_a(target);
@@ -1252,6 +1257,7 @@ static int cortex_a_debug_entry(struct target *target)
        if (cortex_a->fast_reg_read)
                target_alloc_working_area(target, 64, &regfile_working_area);
 
+
        /* First load register acessible through core debug port*/
        if (!regfile_working_area)
                retval = arm_dpm_read_current_registers(&armv7a->dpm);
@@ -1296,6 +1302,17 @@ static int cortex_a_debug_entry(struct target *target)
                reg->dirty = reg->valid;
        }
 
+       /* read Saved PSR */
+       retval = cortex_a_dap_read_coreregister_u32(target, &spsr, 17);
+       /*  store current spsr */
+       if (retval != ERROR_OK)
+               return retval;
+
+       reg = arm->spsr;
+       buf_set_u32(reg->value, 0, 32, spsr);
+       reg->valid = 1;
+       reg->dirty = 0;
+
 #if 0
 /* TODO, Move this */
        uint32_t cp15_control_register, cp15_cacr, cp15_nacr;
@@ -1921,7 +1938,8 @@ static int cortex_a_assert_reset(struct target *target)
        }
 
        /* registers are now invalid */
-       register_cache_invalidate(armv7a->arm.core_cache);
+       if (target_was_examined(target))
+               register_cache_invalidate(armv7a->arm.core_cache);
 
        target->state = TARGET_RESET;
 
@@ -1937,17 +1955,22 @@ static int cortex_a_deassert_reset(struct target *target)
        /* be certain SRST is off */
        jtag_add_reset(0, 0);
 
-       retval = cortex_a_poll(target);
-       if (retval != ERROR_OK)
-               return retval;
+       if (target_was_examined(target)) {
+               retval = cortex_a_poll(target);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
        if (target->reset_halt) {
                if (target->state != TARGET_HALTED) {
                        LOG_WARNING("%s: ran after reset and before halt ...",
                                target_name(target));
-                       retval = target_halt(target);
-                       if (retval != ERROR_OK)
-                               return retval;
+                       if (target_was_examined(target)) {
+                               retval = target_halt(target);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                       } else
+                               target->state = TARGET_UNKNOWN;
                }
        }
 
@@ -2664,7 +2687,7 @@ out:
 /*
  * Cortex-A Memory access
  *
- * This is same Cortex M3 but we must also use the correct
+ * This is same Cortex-M3 but we must also use the correct
  * ap number for every access.
  */
 
@@ -2955,6 +2978,7 @@ static int cortex_a_examine_first(struct target *target)
        struct cortex_a_common *cortex_a = target_to_cortex_a(target);
        struct armv7a_common *armv7a = &cortex_a->armv7a_common;
        struct adiv5_dap *swjdp = armv7a->arm.dap;
+
        int i;
        int retval = ERROR_OK;
        uint32_t didr, ctypr, ttypr, cpuid, dbg_osreg;