Commit 53590217 authored by ntfreak's avatar ntfreak
Browse files

- merged mips target into svn trunk

git-svn-id: svn://svn.berlios.de/openocd/trunk@874 b42882b7-edfa-0310-969c-e2dbd0fdcd60
parent 6f0000e5
...@@ -12,11 +12,12 @@ noinst_LIBRARIES = libtarget.a ...@@ -12,11 +12,12 @@ noinst_LIBRARIES = libtarget.a
libtarget_a_SOURCES = target.c register.c breakpoints.c armv4_5.c embeddedice.c etm.c arm7tdmi.c arm9tdmi.c \ libtarget_a_SOURCES = target.c register.c breakpoints.c armv4_5.c embeddedice.c etm.c arm7tdmi.c arm9tdmi.c \
arm_jtag.c arm7_9_common.c algorithm.c arm920t.c arm720t.c armv4_5_mmu.c armv4_5_cache.c arm_disassembler.c \ arm_jtag.c arm7_9_common.c algorithm.c arm920t.c arm720t.c armv4_5_mmu.c armv4_5_cache.c arm_disassembler.c \
arm966e.c arm926ejs.c feroceon.c etb.c xscale.c arm_simulator.c image.c armv7m.c cortex_m3.c cortex_swjdp.c \ arm966e.c arm926ejs.c feroceon.c etb.c xscale.c arm_simulator.c image.c armv7m.c cortex_m3.c cortex_swjdp.c \
etm_dummy.c $(OOCD_TRACE_FILES) target_request.c trace.c arm11.c arm11_dbgtap.c etm_dummy.c $(OOCD_TRACE_FILES) target_request.c trace.c arm11.c arm11_dbgtap.c mips32.c mips_m4k.c \
mips32_pracc.c mips_ejtag.c
noinst_HEADERS = target.h trace.h register.h armv4_5.h embeddedice.h etm.h arm7tdmi.h arm9tdmi.h \ noinst_HEADERS = target.h trace.h register.h armv4_5.h embeddedice.h etm.h arm7tdmi.h arm9tdmi.h \
arm_jtag.h arm7_9_common.h arm920t.h arm720t.h armv4_5_mmu.h armv4_5_cache.h breakpoints.h algorithm.h \ arm_jtag.h arm7_9_common.h arm920t.h arm720t.h armv4_5_mmu.h armv4_5_cache.h breakpoints.h algorithm.h \
arm_disassembler.h arm966e.h arm926ejs.h etb.h xscale.h arm_simulator.h image.h armv7m.h cortex_m3.h cortex_swjdp.h \ arm_disassembler.h arm966e.h arm926ejs.h etb.h xscale.h arm_simulator.h image.h armv7m.h cortex_m3.h cortex_swjdp.h \
etm_dummy.h oocd_trace.h target_request.h trace.h arm11.h etm_dummy.h oocd_trace.h target_request.h trace.h arm11.h mips32.h mips_m4k.h mips_ejtag.h mips32_pracc.h
nobase_dist_pkglib_DATA = xscale/debug_handler.bin event/at91eb40a_reset.script target/at91eb40a.cfg \ nobase_dist_pkglib_DATA = xscale/debug_handler.bin event/at91eb40a_reset.script target/at91eb40a.cfg \
event/at91r40008_reset.script event/sam7s256_reset.script event/sam7x256_reset.script \ event/at91r40008_reset.script event/sam7s256_reset.script event/sam7x256_reset.script \
...@@ -35,6 +36,6 @@ nobase_dist_pkglib_DATA = xscale/debug_handler.bin event/at91eb40a_reset.script ...@@ -35,6 +36,6 @@ nobase_dist_pkglib_DATA = xscale/debug_handler.bin event/at91eb40a_reset.script
interface/chameleon.cfg interface/at91rm9200.cfg interface/jlink.cfg interface/arm-usb-ocd.cfg \ interface/chameleon.cfg interface/at91rm9200.cfg interface/jlink.cfg interface/arm-usb-ocd.cfg \
interface/signalyzer.cfg event/eir-sam7se512_reset.script target/eir-sam7se512.cfg \ interface/signalyzer.cfg event/eir-sam7se512_reset.script target/eir-sam7se512.cfg \
event/hammer_reset.script interface/flyswatter.cfg target/hammer.cfg target/mx31.cfg \ event/hammer_reset.script interface/flyswatter.cfg target/hammer.cfg target/mx31.cfg \
event/str730_program.script event/str750_program.script interface/olimex-jtag-tiny-a.cfg event/str730_program.script event/str750_program.script interface/olimex-jtag-tiny-a.cfg \
target/pic32mx.cfg
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
* Copyright (C) 2008 by David T.L. Wong *
* *
* 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. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "mips32.h"
#include "jtag.h"
#include "log.h"
#include <stdlib.h>
#include <string.h>
char* mips32_core_reg_list[] =
{
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
"status", "lo", "hi", "badvaddr", "cause", "pc"
};
mips32_core_reg_t mips32_core_reg_list_arch_info[MIPS32NUMCOREREGS] =
{
{0, NULL, NULL},
{1, NULL, NULL},
{2, NULL, NULL},
{3, NULL, NULL},
{4, NULL, NULL},
{5, NULL, NULL},
{6, NULL, NULL},
{7, NULL, NULL},
{8, NULL, NULL},
{9, NULL, NULL},
{10, NULL, NULL},
{11, NULL, NULL},
{12, NULL, NULL},
{13, NULL, NULL},
{14, NULL, NULL},
{15, NULL, NULL},
{16, NULL, NULL},
{17, NULL, NULL},
{18, NULL, NULL},
{19, NULL, NULL},
{20, NULL, NULL},
{21, NULL, NULL},
{22, NULL, NULL},
{23, NULL, NULL},
{24, NULL, NULL},
{25, NULL, NULL},
{26, NULL, NULL},
{27, NULL, NULL},
{28, NULL, NULL},
{29, NULL, NULL},
{30, NULL, NULL},
{31, NULL, NULL},
{32, NULL, NULL},
{33, NULL, NULL},
{34, NULL, NULL},
{35, NULL, NULL},
{36, NULL, NULL},
{37, NULL, NULL},
};
u8 mips32_gdb_dummy_fsr_value[] = {0, 0, 0, 0};
reg_t mips32_gdb_dummy_fsr_reg =
{
"GDB dummy floating-point status register", mips32_gdb_dummy_fsr_value, 0, 1, 32, NULL, 0, NULL, 0
};
u8 mips32_gdb_dummy_fir_value[] = {0, 0, 0, 0};
reg_t mips32_gdb_dummy_fir_reg =
{
"GDB dummy floating-point register", mips32_gdb_dummy_fir_value, 0, 1, 32, NULL, 0, NULL, 0
};
int mips32_core_reg_arch_type = -1;
int mips32_get_core_reg(reg_t *reg)
{
int retval;
mips32_core_reg_t *mips32_reg = reg->arch_info;
target_t *target = mips32_reg->target;
mips32_common_t *mips32_target = target->arch_info;
if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED;
}
retval = mips32_target->read_core_reg(target, mips32_reg->num);
return retval;
}
int mips32_set_core_reg(reg_t *reg, u8 *buf)
{
mips32_core_reg_t *mips32_reg = reg->arch_info;
target_t *target = mips32_reg->target;
u32 value = buf_get_u32(buf, 0, 32);
if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED;
}
buf_set_u32(reg->value, 0, 32, value);
reg->dirty = 1;
reg->valid = 1;
return ERROR_OK;
}
int mips32_read_core_reg(struct target_s *target, int num)
{
u32 reg_value;
mips32_core_reg_t *mips_core_reg;
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
if ((num < 0) || (num >= MIPS32NUMCOREREGS))
return ERROR_INVALID_ARGUMENTS;
mips_core_reg = mips32->core_cache->reg_list[num].arch_info;
reg_value = mips32->core_regs[num];
buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
mips32->core_cache->reg_list[num].valid = 1;
mips32->core_cache->reg_list[num].dirty = 0;
return ERROR_OK;
}
int mips32_write_core_reg(struct target_s *target, int num)
{
u32 reg_value;
mips32_core_reg_t *mips_core_reg;
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
if ((num < 0) || (num >= MIPS32NUMCOREREGS))
return ERROR_INVALID_ARGUMENTS;
reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
mips_core_reg = mips32->core_cache->reg_list[num].arch_info;
mips32->core_regs[num] = reg_value;
LOG_DEBUG("write core reg %i value 0x%x", num , reg_value);
mips32->core_cache->reg_list[num].valid = 1;
mips32->core_cache->reg_list[num].dirty = 0;
return ERROR_OK;
}
int mips32_invalidate_core_regs(target_t *target)
{
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
int i;
for (i = 0; i < mips32->core_cache->num_regs; i++)
{
mips32->core_cache->reg_list[i].valid = 0;
mips32->core_cache->reg_list[i].dirty = 0;
}
return ERROR_OK;
}
int mips32_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size)
{
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
int i;
/* include fsr/fir reg */
*reg_list_size = MIPS32NUMCOREREGS + 2;
*reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
for (i = 0; i < MIPS32NUMCOREREGS; i++)
{
(*reg_list)[i] = &mips32->core_cache->reg_list[i];
}
/* add dummy floating points regs */
(*reg_list)[38] = &mips32_gdb_dummy_fsr_reg;
(*reg_list)[39] = &mips32_gdb_dummy_fir_reg;
return ERROR_OK;
}
int mips32_save_context(target_t *target)
{
int i;
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
/* read core registers */
mips32_pracc_read_regs(ejtag_info, mips32->core_regs);
for (i = 0; i < MIPS32NUMCOREREGS; i++)
{
if (!mips32->core_cache->reg_list[i].valid)
{
mips32->read_core_reg(target, i);
}
}
return ERROR_OK;
}
int mips32_restore_context(target_t *target)
{
int i;
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
for (i = 0; i < MIPS32NUMCOREREGS; i++)
{
if (mips32->core_cache->reg_list[i].dirty)
{
mips32->write_core_reg(target, i);
}
}
/* write core regs */
mips32_pracc_write_regs(ejtag_info, mips32->core_regs);
return ERROR_OK;
}
int mips32_arch_state(struct target_s *target)
{
mips32_common_t *mips32 = target->arch_info;
if (mips32->common_magic != MIPS32_COMMON_MAGIC)
{
LOG_ERROR("BUG: called for a non-MIPS32 target");
exit(-1);
}
LOG_USER("target halted due to %s, pc: 0x%8.8x",
target_debug_reason_strings[target->debug_reason],
buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
return ERROR_OK;
}
reg_cache_t *mips32_build_reg_cache(target_t *target)
{
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
int num_regs = MIPS32NUMCOREREGS;
reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
reg_cache_t *cache = malloc(sizeof(reg_cache_t));
reg_t *reg_list = malloc(sizeof(reg_t) * num_regs);
mips32_core_reg_t *arch_info = malloc(sizeof(mips32_core_reg_t) * num_regs);
int i;
if (mips32_core_reg_arch_type == -1)
mips32_core_reg_arch_type = register_reg_arch_type(mips32_get_core_reg, mips32_set_core_reg);
/* Build the process context cache */
cache->name = "mips32 registers";
cache->next = NULL;
cache->reg_list = reg_list;
cache->num_regs = num_regs;
(*cache_p) = cache;
mips32->core_cache = cache;
for (i = 0; i < num_regs; i++)
{
arch_info[i] = mips32_core_reg_list_arch_info[i];
arch_info[i].target = target;
arch_info[i].mips32_common = mips32;
reg_list[i].name = mips32_core_reg_list[i];
reg_list[i].size = 32;
reg_list[i].value = calloc(1, 4);
reg_list[i].dirty = 0;
reg_list[i].valid = 0;
reg_list[i].bitfield_desc = NULL;
reg_list[i].num_bitfields = 0;
reg_list[i].arch_type = mips32_core_reg_arch_type;
reg_list[i].arch_info = &arch_info[i];
}
return cache;
}
int mips32_init_arch_info(target_t *target, mips32_common_t *mips32, int chain_pos, char *variant)
{
target->arch_info = mips32;
mips32->common_magic = MIPS32_COMMON_MAGIC;
mips32->ejtag_info.chain_pos = chain_pos;
mips32->read_core_reg = mips32_read_core_reg;
mips32->write_core_reg = mips32_write_core_reg;
return ERROR_OK;
}
int mips32_register_commands(struct command_context_s *cmd_ctx)
{
return ERROR_OK;
}
int mips32_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info)
{
/*TODO*/
return ERROR_OK;
}
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
* Copyright (C) 2008 by David T.L. Wong *
* *
* 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. *
***************************************************************************/
#ifndef MIPS32_H
#define MIPS32_H
#include "target.h"
#include "register.h"
#include "mips_ejtag.h"
#include "mips32_pracc.h"
#define MIPS32_COMMON_MAGIC 0xB320B320
/* offsets into mips32 core register cache */
enum
{
MIPS32_PC = 37,
MIPS32NUMCOREREGS
};
typedef struct mips32_common_s
{
int common_magic;
void *arch_info;
reg_cache_t *core_cache;
mips_ejtag_t ejtag_info;
u32 core_regs[MIPS32NUMCOREREGS];
/* register cache to processor synchronization */
int (*read_core_reg)(struct target_s *target, int num);
int (*write_core_reg)(struct target_s *target, int num);
} mips32_common_t;
typedef struct mips32_core_reg_s
{
u32 num;
target_t *target;
mips32_common_t *mips32_common;
} mips32_core_reg_t;
#define MIPS32_OP_BEQ 0x04
#define MIPS32_OP_ADDI 0x08
#define MIPS32_OP_AND 0x24
#define MIPS32_OP_COP0 0x10
#define MIPS32_OP_LUI 0x0F
#define MIPS32_OP_LW 0x23
#define MIPS32_OP_LBU 0x24
#define MIPS32_OP_LHU 0x25
#define MIPS32_OP_MFHI 0x10
#define MIPS32_OP_MFLO 0x12
#define MIPS32_OP_SB 0x28
#define MIPS32_OP_SH 0x29
#define MIPS32_OP_SW 0x2B
#define MIPS32_OP_ORI 0x0D
#define MIPS32_COP0_MF 0x00
#define MIPS32_COP0_MT 0x04
#define MIPS32_R_INST(opcode, rs, rt, rd, shamt, funct) (((opcode)<<26) |((rs)<<21)|((rt)<<16)|((rd)<<11)| ((shamt)<<5) | (funct))
#define MIPS32_I_INST(opcode, rs, rt, immd) (((opcode)<<26) |((rs)<<21)|((rt)<<16)|(immd))
#define MIPS32_J_INST(opcode, addr) (((opcode)<<26) |(addr))
#define MIPS32_NOP 0
#define MIPS32_ADDI(tar, src, val) MIPS32_I_INST(MIPS32_OP_ADDI, src, tar, val)
#define MIPS32_AND(reg, off, val) MIPS32_R_INST(0, off, val, reg, 0, MIPS32_OP_AND)
#define MIPS32_B(off) MIPS32_BEQ(0, 0, off)
#define MIPS32_BEQ(src,tar,off) MIPS32_I_INST(MIPS32_OP_BEQ, src, tar, off)
#define MIPS32_MFC0(gpr, cpr, sel) MIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MF, gpr, cpr, 0, sel)
#define MIPS32_MTC0(gpr,cpr, sel) MIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MT, gpr, cpr, 0, sel)
#define MIPS32_LBU(reg, off, base) MIPS32_I_INST(MIPS32_OP_LBU, base, reg, off)
#define MIPS32_LHU(reg, off, base) MIPS32_I_INST(MIPS32_OP_LHU, base, reg, off)
#define MIPS32_LUI(reg, val) MIPS32_I_INST(MIPS32_OP_LUI, 0, reg, val)
#define MIPS32_LW(reg, off, base) MIPS32_I_INST(MIPS32_OP_LW, base, reg, off)
#define MIPS32_LO(reg) MIPS32_R_INST(0, 0, 0, reg, 0, MIPS32_OP_MFHI)
#define MIPS32_HI(reg) MIPS32_R_INST(0, 0, 0, reg, 0, MIPS32_OP_MFLO)
#define MIPS32_ORI(src, tar, val) MIPS32_I_INST(MIPS32_OP_ORI, src, tar, val)
#define MIPS32_SB(reg, off, base) MIPS32_I_INST(MIPS32_OP_SB, base, reg, off)
#define MIPS32_SH(reg, off, base) MIPS32_I_INST(MIPS32_OP_SH, base, reg, off)
#define MIPS32_SW(reg, off, base) MIPS32_I_INST(MIPS32_OP_SW, base, reg, off)
#define MIPS32_DRET 0x4200001F
extern int mips32_arch_state(struct target_s *target);
extern int mips32_init_arch_info(target_t *target, mips32_common_t *mips32, int chain_pos, char *variant);
extern int mips32_restore_context(target_t *target);
extern int mips32_save_context(target_t *target);
extern reg_cache_t *mips32_build_reg_cache(target_t *target);
extern int mips32_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info);
extern int mips32_register_commands(struct command_context_s *cmd_ctx);
extern int mips32_invalidate_core_regs(target_t *target);
extern int mips32_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size);
#endif /*MIPS32_H*/
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
* Copyright (C) 2008 by David T.L. Wong *
* *
* 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. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "log.h"
#include "mips32.h"
#include "mips32_pracc.h"
typedef struct {
u32 *local_iparam;
int num_iparam;
u32 *local_oparam;
int num_oparam;
u32 *code;
int code_len;
u32 stack[32];
int stack_offset;
mips_ejtag_t *ejtag_info;
} mips32_pracc_context;
static int wait_for_pracc_rw(mips_ejtag_t *ejtag_info, u32 *ctrl)
{
u32 ejtag_ctrl;
while (1)
{
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
ejtag_ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
if (ejtag_ctrl & EJTAG_CTRL_PRACC)
break;
LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
return ERROR_JTAG_DEVICE_ERROR;
}
*ctrl = ejtag_ctrl;
return ERROR_OK;
}
static int mips32_pracc_exec_read(mips32_pracc_context *ctx, u32 address)
{
int offset;
u32 ctrl, data;
if ((address >= MIPS32_PRACC_PARAM_IN)
&& (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
{
offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
data = ctx->local_iparam[offset];
}
else if ((address >= MIPS32_PRACC_PARAM_OUT)
&& (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))
{
offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
data = ctx->local_oparam[offset];
}
else if ((address >= MIPS32_PRACC_TEXT)
&& (address <= MIPS32_PRACC_TEXT + ctx->code_len*4))
{
offset = (address - MIPS32_PRACC_TEXT) / 4;
data = ctx->code[offset];
}
else if (address == MIPS32_PRACC_STACK)
{
/* save to our debug stack */
data = ctx->stack[--ctx->stack_offset];
}
else
{
/* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
* to start of debug vector */
data = 0;
LOG_ERROR("Error reading unexpected address");
return ERROR_JTAG_DEVICE_ERROR;
}
/* Send the data out */
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
mips_ejtag_drscan_32(ctx->ejtag_info, &data);
/* Clear the access pending bit (let the processor eat!) */
ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL, NULL);
mips_ejtag_drscan_32(ctx->ejtag_info, &ctrl);
return ERROR_OK;
}
static int mips32_pracc_exec_write(mips32_pracc_context *ctx, u32 address)
{
u32 ctrl,data;
int offset;
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
mips_ejtag_drscan_32(ctx->ejtag_info, &data);
/* Clear access pending bit */
ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL, NULL);
mips_ejtag_drscan_32(ctx->ejtag_info, &ctrl);
if ((address >= MIPS32_PRACC_PARAM_IN)
&& (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
{
offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
ctx->local_iparam[offset] = data;
}
else if ((address >= MIPS32_PRACC_PARAM_OUT )
&& (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))
{
offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
ctx->local_oparam[offset] = data;
}
else if (address == MIPS32_PRACC_STACK)
{
/* save data onto our stack */
ctx->stack[ctx->stack_offset++] = data;
}
else