]> git.sur5r.net Git - openocd/blobdiff - src/target/feroceon.c
Edgar Grimberg sharpened the str912 target script.
[openocd] / src / target / feroceon.c
index e1a4e955d50676b8f6c887ff6a44761b3d822db2..bad110e061a41c8ec84846b619bb205a7868ad1a 100644 (file)
@@ -1,26 +1,26 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Marvell Semiconductors, Inc.                    *
+ *   Written by Nicolas Pitre <nico@marvell.com>                           *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
 /*
  * Marvell Feroceon (88F5182, 88F5281) support.
  *
- * Copyright (C) 2008 Marvell Semiconductors, Inc.
- * Written by Nicolas Pitre <nico@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify 
- * it under the terms of the GNU General Public License as published by 
- * the Free Software Foundation; either version 2 of the License, or 
- * (at your option) any later version. 
- *  
- * This program is distributed in the hope that it will be useful, 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
- * 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., 
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*
  * The Feroceon core mimics the ARM926 ICE interface with the following
  * differences:
  *
@@ -229,7 +229,7 @@ void feroceon_write_xpsr(target_t *target, u32 xpsr, int spsr)
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
        arm_jtag_t *jtag_info = &arm7_9->jtag_info;
                
-       DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
+       LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
 
        arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
        arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
@@ -270,7 +270,7 @@ void feroceon_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
        arm_jtag_t *jtag_info = &arm7_9->jtag_info;
 
-       DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
+       LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
 
        arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
        arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
@@ -320,7 +320,7 @@ void feroceon_branch_resume(target_t *target)
 
 void feroceon_branch_resume_thumb(target_t *target)
 {
-       DEBUG("-");
+       LOG_DEBUG("-");
        
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
@@ -362,6 +362,47 @@ void feroceon_branch_resume_thumb(target_t *target)
        arm_jtag_set_instr(jtag_info, 0xf, NULL);
 }
 
+int feroceon_read_cp15(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 *value)
+{
+       armv4_5_common_t *armv4_5 = target->arch_info;
+       arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+       arm_jtag_t *jtag_info = &arm7_9->jtag_info;
+       int err;
+
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_MRC(15, op1, 0, CRn, CRm, op2), 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
+       err = arm7_9_execute_sys_speed(target);
+       if (err != ERROR_OK)
+               return err;
+
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, 1, 0, 0), 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, value, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+       return jtag_execute_queue();
+}
+
+int feroceon_write_cp15(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 value)
+{
+       armv4_5_common_t *armv4_5 = target->arch_info;
+       arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+       arm_jtag_t *jtag_info = &arm7_9->jtag_info;
+
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 1, 0, 0), 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, value, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_MCR(15, op1, 0, CRn, CRm, op2), 0, NULL, 0);
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
+       return arm7_9_execute_sys_speed(target);
+}
+
 void feroceon_enable_single_step(target_t *target)
 {
        armv4_5_common_t *armv4_5 = target->arch_info;
@@ -374,7 +415,7 @@ void feroceon_enable_single_step(target_t *target)
                u32 current_pc, current_opcode;
                current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
                target_read_u32(target, current_pc, &current_opcode);
-               ERROR("BUG: couldn't calculate PC of next instruction, "
+               LOG_ERROR("BUG: couldn't calculate PC of next instruction, "
                      "current opcode is 0x%8.8x", current_opcode);
                next_pc = current_pc;
        }
@@ -400,7 +441,6 @@ void feroceon_disable_single_step(target_t *target)
        embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
 }
 
-
 int feroceon_examine_debug_reason(target_t *target)
 {
        /* the MOE is not implemented */
@@ -461,7 +501,7 @@ int feroceon_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buf
                /* make sure we have a working area */
                if (target_alloc_working_area(target, dcc_size, &arm7_9->dcc_working_area) != ERROR_OK)
                {
-                       INFO("no working area available, falling back to memory writes");
+                       LOG_INFO("no working area available, falling back to memory writes");
                        return target->type->write_memory(target, address, 4, count, buffer);
                }
 
@@ -538,7 +578,7 @@ int feroceon_init_target(struct command_context_s *cmd_ctx, struct target_s *tar
 
        /* the COMMS_CTRL bits are all contiguous */
        if (buf_get_u32(arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL].value, 2, 4) != 6)
-               ERROR("unexpected Feroceon EICE version signature");
+               LOG_ERROR("unexpected Feroceon EICE version signature");
 
        arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].size = 6; 
        arm7_9->eice_cache->reg_list[EICE_DBG_STAT].size = 5; 
@@ -569,10 +609,11 @@ int feroceon_target_command(struct command_context_s *cmd_ctx, char *cmd, char *
        armv4_5_common_t *armv4_5;
        arm7_9_common_t *arm7_9;
        arm926ejs_common_t *arm926ejs = malloc(sizeof(arm926ejs_common_t));
+       memset(arm926ejs, 0, sizeof(*arm926ejs));
        
        if (argc < 4)
        {
-               ERROR("'target arm926ejs' requires at least one additional argument");
+               LOG_ERROR("'target arm926ejs' requires at least one additional argument");
                exit(-1);
        }
        
@@ -581,7 +622,7 @@ int feroceon_target_command(struct command_context_s *cmd_ctx, char *cmd, char *
        if (argc >= 5)
                variant = args[4];
        
-       DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
+       LOG_DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
        
        arm926ejs_init_arch_info(target, arm926ejs, chain_pos, variant);
 
@@ -606,6 +647,10 @@ int feroceon_target_command(struct command_context_s *cmd_ctx, char *cmd, char *
        /* MOE is not implemented */
        arm7_9->examine_debug_reason = feroceon_examine_debug_reason;
 
+       /* the standard ARM926 methods don't always work (don't ask...) */
+       arm926ejs->read_cp15 = feroceon_read_cp15;
+       arm926ejs->write_cp15 = feroceon_write_cp15;
+
        /* asserting DBGRQ won't win over the undef exception */
        arm7_9->use_dbgrq = 0;