Exemplo n.º 1
0
static void arm9tdmi_build_reg_cache(struct target *target)
{
	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct arm *arm = target_to_arm(target);

	(*cache_p) = arm_build_reg_cache(target, arm);
}
Exemplo n.º 2
0
/** Builds cache of architecturally defined registers.  */
struct reg_cache *armv7m_build_reg_cache(struct target *target)
{
	struct armv7m_common *armv7m = target_to_armv7m(target);
	struct arm *arm = &armv7m->arm;
	int num_regs = ARMV7M_NUM_REGS;
	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
	struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
	struct reg_feature *feature;
	int i;

	/* Build the process context cache */
	cache->name = "arm v7m registers";
	cache->next = NULL;
	cache->reg_list = reg_list;
	cache->num_regs = num_regs;
	(*cache_p) = cache;

	for (i = 0; i < num_regs; i++) {
		arch_info[i].num = armv7m_regs[i].id;
		arch_info[i].target = target;
		arch_info[i].arm = arm;

		reg_list[i].name = armv7m_regs[i].name;
		reg_list[i].size = armv7m_regs[i].bits;
		size_t storage_size = DIV_ROUND_UP(armv7m_regs[i].bits, 8);
		if (storage_size < 4)
			storage_size = 4;
		reg_list[i].value = calloc(1, storage_size);
		reg_list[i].dirty = 0;
		reg_list[i].valid = 0;
		reg_list[i].type = &armv7m_reg_type;
		reg_list[i].arch_info = &arch_info[i];

		reg_list[i].group = armv7m_regs[i].group;
		reg_list[i].number = i;
		reg_list[i].exist = true;
		reg_list[i].caller_save = true;	/* gdb defaults to true */

		feature = calloc(1, sizeof(struct reg_feature));
		if (feature) {
			feature->name = armv7m_regs[i].feature;
			reg_list[i].feature = feature;
		} else
			LOG_ERROR("unable to allocate feature list");

		reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
		if (reg_list[i].reg_data_type)
			reg_list[i].reg_data_type->type = armv7m_regs[i].type;
		else
			LOG_ERROR("unable to allocate reg type list");
	}

	arm->cpsr = reg_list + ARMV7M_xPSR;
	arm->pc = reg_list + ARMV7M_PC;
	arm->core_cache = cache;

	return cache;
}
Exemplo n.º 3
0
static struct reg_cache *avr32_build_reg_cache(struct target *target)
{
	int num_regs = AVR32NUMCOREREGS;
	struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
	struct avr32_core_reg *arch_info =
		malloc(sizeof(struct avr32_core_reg) * num_regs);
	int i;

	/* Build the process context cache */
	cache->name = "avr32 registers";
	cache->next = NULL;
	cache->reg_list = reg_list;
	cache->num_regs = num_regs;
	(*cache_p) = cache;
	ap7k->core_cache = cache;

	for (i = 0; i < num_regs; i++) {
		arch_info[i] = avr32_core_reg_list_arch_info[i];
		arch_info[i].target = target;
		arch_info[i].avr32_common = ap7k;
		reg_list[i].name = avr32_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].type = &avr32_reg_type;
		reg_list[i].arch_info = &arch_info[i];
	}

	return cache;
}
Exemplo n.º 4
0
struct reg_cache *lakemont_build_reg_cache(struct target *t)
{
	struct x86_32_common *x86_32 = target_to_x86_32(t);
	int num_regs = ARRAY_SIZE(regs);
	struct reg_cache **cache_p = register_get_last_cache_p(&t->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
	struct lakemont_core_reg *arch_info = malloc(sizeof(struct lakemont_core_reg) * num_regs);
	struct reg_feature *feature;
	int i;

	if (cache == NULL || reg_list == NULL || arch_info == NULL) {
		free(cache);
		free(reg_list);
		free(arch_info);
		LOG_ERROR("%s out of memory", __func__);
		return NULL;
	}

	/* Build the process context cache */
	cache->name = "lakemont registers";
	cache->next = NULL;
	cache->reg_list = reg_list;
	cache->num_regs = num_regs;
	(*cache_p) = cache;
	x86_32->cache = cache;

	for (i = 0; i < num_regs; i++) {
		arch_info[i].target = t;
		arch_info[i].x86_32_common = x86_32;
		arch_info[i].op = regs[i].op;
		arch_info[i].pm_idx = regs[i].pm_idx;
		reg_list[i].name = regs[i].name;
		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].type = &lakemont_reg_type;
		reg_list[i].arch_info = &arch_info[i];

		reg_list[i].group = regs[i].group;
		reg_list[i].number = i;
		reg_list[i].exist = true;
		reg_list[i].caller_save = true;	/* gdb defaults to true */

		feature = calloc(1, sizeof(struct reg_feature));
		if (feature) {
			feature->name = regs[i].feature;
			reg_list[i].feature = feature;
		} else
			LOG_ERROR("%s unable to allocate feature list", __func__);

		reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
		if (reg_list[i].reg_data_type)
			reg_list[i].reg_data_type->type = regs[i].type;
		else
			LOG_ERROR("%s unable to allocate reg type list", __func__);
	}
	return cache;
}
Exemplo n.º 5
0
static void xtensa_build_reg_cache(struct target *target)
{
	struct xtensa_common *xtensa = target_to_xtensa(target);
	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = calloc(XT_NUM_REGS, sizeof(struct reg));
	struct xtensa_core_reg *arch_info = malloc(
			sizeof(struct xtensa_core_reg) * XT_NUM_REGS);
	uint8_t i;

	cache->name = "Xtensa registers";
	cache->next = NULL;
	cache->reg_list = reg_list;
	cache->num_regs = XT_NUM_REGS;
	(*cache_p)= cache;
	xtensa->core_cache = cache;

	for(i = 0; i < XT_NUM_REGS; i++) {
		assert(xt_regs[i].idx == i && "xt_regs[] entry idx field should match index in array");
		arch_info[i] = xt_regs[i];
		arch_info[i].target = target;
		if(arch_info[i].type == XT_REG_ALIASED) {
			/* NB: This is a constant at the moment, but will eventually be target-specific */
			arch_info[i].reg_num += XT_DEBUGLEVEL;
		}
		reg_list[i].name = arch_info[i].name;
		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].type = &xtensa_reg_type;
		reg_list[i].arch_info = &arch_info[i];
	}
}
Exemplo n.º 6
0
static struct reg_cache *or1k_build_reg_cache(struct target *target)
{
	int num_regs = OR1KNUMCOREREGS;
	struct or1k_common *or1k = target_to_or1k(target);
	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
	struct or1k_core_reg *arch_info = 
		malloc(sizeof(struct or1k_core_reg) * num_regs);
	int i;

	/* Build the process context cache */
	cache->name = "openrisc 1000 registers";
	cache->next = NULL;
	cache->reg_list = reg_list;
	cache->num_regs = num_regs;
	(*cache_p) = cache;
	or1k->core_cache = cache;

	for (i = 0; i < num_regs; i++)
	{
		arch_info[i] = or1k_core_reg_list_arch_info[i];
		arch_info[i].target = target;
		arch_info[i].or1k_common = or1k;
		reg_list[i].name = or1k_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].type = &or1k_reg_type;
		reg_list[i].arch_info = &arch_info[i];
	}

	return cache;
}
Exemplo n.º 7
0
void arm9tdmi_build_reg_cache(target_t *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;

	(*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
	armv4_5->core_cache = (*cache_p);
}
Exemplo n.º 8
0
/**
 * Hooks up this DPM to its associated target; call only once.
 * Initially this only covers the register cache.
 *
 * Oh, and watchpoints.  Yeah.
 */
int arm_dpm_setup(struct arm_dpm *dpm)
{
	struct arm *arm = dpm->arm;
	struct target *target = arm->target;
	struct reg_cache *cache;

	arm->dpm = dpm;

	/* register access setup */
	arm->full_context = arm_dpm_full_context;
	arm->read_core_reg = arm_dpm_read_core_reg;
	arm->write_core_reg = arm_dpm_write_core_reg;

	cache = arm_build_reg_cache(target, arm);
	if (!cache)
		return ERROR_FAIL;

	*register_get_last_cache_p(&target->reg_cache) = cache;

	/* coprocessor access setup */
	arm->mrc = dpm_mrc;
	arm->mcr = dpm_mcr;

	/* breakpoint setup -- optional until it works everywhere */
	if (!target->type->add_breakpoint) {
		target->type->add_breakpoint = dpm_add_breakpoint;
		target->type->remove_breakpoint = dpm_remove_breakpoint;
	}

	/* watchpoint setup */
	target->type->add_watchpoint = dpm_add_watchpoint;
	target->type->remove_watchpoint = dpm_remove_watchpoint;

	/* FIXME add vector catch support */

	dpm->nbp = 1 + ((dpm->didr >> 24) & 0xf);
	dpm->dbp = calloc(dpm->nbp, sizeof *dpm->dbp);

	dpm->nwp = 1 + ((dpm->didr >> 28) & 0xf);
	dpm->dwp = calloc(dpm->nwp, sizeof *dpm->dwp);

	if (!dpm->dbp || !dpm->dwp) {
		free(dpm->dbp);
		free(dpm->dwp);
		return ERROR_FAIL;
	}

	LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
		target_name(target), dpm->nbp, dpm->nwp);

	/* REVISIT ... and some of those breakpoints could match
	 * execution context IDs...
	 */

	return ERROR_OK;
}
Exemplo n.º 9
0
static struct reg_cache *or1k_build_reg_cache(struct target *target)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = calloc(or1k->nb_regs, sizeof(struct reg));
	struct or1k_core_reg *arch_info =
		malloc((or1k->nb_regs) * sizeof(struct or1k_core_reg));
	struct reg_feature *feature;

	LOG_DEBUG("-");

	/* Build the process context cache */
	cache->name = "OpenRISC 1000 registers";
	cache->next = NULL;
	cache->reg_list = reg_list;
	cache->num_regs = or1k->nb_regs;
	(*cache_p) = cache;
	or1k->core_cache = cache;
	or1k->arch_info = arch_info;

	for (int i = 0; i < or1k->nb_regs; i++) {
		arch_info[i] = or1k_core_reg_list_arch_info[i];
		arch_info[i].target = target;
		arch_info[i].or1k_common = or1k;
		reg_list[i].name = or1k_core_reg_list_arch_info[i].name;

		feature = malloc(sizeof(struct reg_feature));
		feature->name = or1k_core_reg_list_arch_info[i].feature;
		reg_list[i].feature = feature;

		reg_list[i].group = or1k_core_reg_list_arch_info[i].group;
		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].type = &or1k_reg_type;
		reg_list[i].arch_info = &arch_info[i];
		reg_list[i].number = i;
		reg_list[i].exist = true;
	}

	return cache;
}
Exemplo n.º 10
0
/** Builds cache of architecturally defined registers.  */
struct reg_cache *armv7m_build_reg_cache(struct target *target)
{
	struct armv7m_common *armv7m = target_to_armv7m(target);
	struct arm *arm = &armv7m->arm;
	int num_regs = ARMV7M_NUM_REGS;
	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
	struct armv7m_core_reg *arch_info = calloc(num_regs, sizeof(struct armv7m_core_reg));
	int i;

#ifdef ARMV7_GDB_HACKS
	register_init_dummy(&armv7m_gdb_dummy_cpsr_reg);
#endif

	/* Build the process context cache */
	cache->name = "arm v7m registers";
	cache->next = NULL;
	cache->reg_list = reg_list;
	cache->num_regs = num_regs;
	(*cache_p) = cache;
	armv7m->core_cache = cache;

	for (i = 0; i < num_regs; i++)
	{
		arch_info[i].num = armv7m_regs[i].id;
		arch_info[i].target = target;
		arch_info[i].armv7m_common = armv7m;
		reg_list[i].name = armv7m_regs[i].name;
		reg_list[i].size = armv7m_regs[i].bits;
		reg_list[i].value = calloc(1, 4);
		reg_list[i].dirty = 0;
		reg_list[i].valid = 0;
		reg_list[i].type = &armv7m_reg_type;
		reg_list[i].arch_info = &arch_info[i];
	}

	arm->cpsr = reg_list + ARMV7M_xPSR;
	arm->pc = reg_list + ARMV7M_PC;
	arm->core_cache = cache;
	return cache;
}
Exemplo n.º 11
0
int dsp563xx_init_target(struct command_context *cmd_ctx, struct target *target)
{
	/* get pointers to arch-specific information */
	struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);

	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = malloc(sizeof(struct reg) * DSP563XX_NUMCOREREGS);
	struct dsp563xx_core_reg *arch_info =
		malloc(sizeof(struct dsp563xx_core_reg) * DSP563XX_NUMCOREREGS);
	int i;

	LOG_DEBUG("%s", __FUNCTION__);

	/* Build the process context cache */
	cache->name = "dsp563xx registers";
	cache->next = NULL;
	cache->reg_list = reg_list;
	cache->num_regs = DSP563XX_NUMCOREREGS;
	(*cache_p) = cache;
	dsp563xx->core_cache = cache;

	for (i = 0; i < DSP563XX_NUMCOREREGS; i++)
	{
		arch_info[i].num = dsp563xx_regs[i].id;
		arch_info[i].name = dsp563xx_regs[i].name;
		arch_info[i].size = dsp563xx_regs[i].bits;
		arch_info[i].r_cmd = dsp563xx_regs[i].r_cmd;
		arch_info[i].w_cmd = dsp563xx_regs[i].w_cmd;
		arch_info[i].target = target;
		arch_info[i].dsp563xx_common = dsp563xx;
		reg_list[i].name = dsp563xx_regs[i].name;
		reg_list[i].size = dsp563xx_regs[i].bits;
		reg_list[i].value = calloc(1, 4);
		reg_list[i].dirty = 0;
		reg_list[i].valid = 0;
		reg_list[i].type = &dsp563xx_reg_type;
		reg_list[i].arch_info = &arch_info[i];
	}

	return ERROR_OK;
}
Exemplo n.º 12
0
void arm9tdmi_build_reg_cache(target_t *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;
	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
	arm_jtag_t *jtag_info = &arm7_9->jtag_info;

	(*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
	armv4_5->core_cache = (*cache_p);
	
	/* one extra register (vector catch) */
	(*cache_p)->next = embeddedice_build_reg_cache(target, arm7_9);
	arm7_9->eice_cache = (*cache_p)->next;

	if (arm7_9->etm_ctx)
	{
		(*cache_p)->next->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
		arm7_9->etm_ctx->reg_cache = (*cache_p)->next->next;
	}
}
Exemplo n.º 13
0
struct reg_cache *mips32_build_reg_cache(struct target *target)
{
	/* get pointers to arch-specific information */
	struct mips32_common *mips32 = target_to_mips32(target);

	int num_regs = MIPS32NUMCOREREGS;
	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
	struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);
	int i;

	register_init_dummy(&mips32_gdb_dummy_fp_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].type = &mips32_reg_type;
		reg_list[i].arch_info = &arch_info[i];
	}

	return cache;
}
Exemplo n.º 14
0
int arm9tdmi_examine(struct target_s *target)
{
	/* get pointers to arch-specific information */
	int retval;
	armv4_5_common_t *armv4_5 = target->arch_info;
	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
	if (!target->type->examined)
	{
		reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
		reg_cache_t *t;
		/* one extra register (vector catch) */
		t=embeddedice_build_reg_cache(target, arm7_9);
		if (t==NULL)
			return ERROR_FAIL;
		(*cache_p) = t;
		arm7_9->eice_cache = (*cache_p);

		if (arm7_9->etm_ctx)
		{
			arm_jtag_t *jtag_info = &arm7_9->jtag_info;
			(*cache_p)->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
			arm7_9->etm_ctx->reg_cache = (*cache_p)->next;
		}
		target->type->examined = 1;
	}
	if ((retval=embeddedice_setup(target))!=ERROR_OK)
		return retval;
	if ((retval=arm7_9_setup(target))!=ERROR_OK)
		return retval;
	if (arm7_9->etm_ctx)
	{
		if ((retval=etm_setup(target))!=ERROR_OK)
			return retval;
	}
	return ERROR_OK;
}
Exemplo n.º 15
0
/* talk to the target and set things up */
static int arm11_examine(struct target *target)
{
	int retval;
	char *type;
	struct arm11_common *arm11 = target_to_arm11(target);
	uint32_t didr, device_id;
	uint8_t implementor;

	/* FIXME split into do-first-time and do-every-time logic ... */

	/* check IDCODE */

	arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);

	struct scan_field		idcode_field;

	arm11_setup_field(arm11, 32, NULL, &device_id, &idcode_field);

	arm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &idcode_field, TAP_DRPAUSE);

	/* check DIDR */

	arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT);

	arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);

	struct scan_field		chain0_fields[2];

	arm11_setup_field(arm11, 32, NULL, &didr, chain0_fields + 0);
	arm11_setup_field(arm11,  8, NULL, &implementor, chain0_fields + 1);

	arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain0_fields), chain0_fields, TAP_IDLE);

	CHECK_RETVAL(jtag_execute_queue());

	/* assume the manufacturer id is ok; check the part # */
	switch ((device_id >> 12) & 0xFFFF)
	{
	case 0x7B36:
		type = "ARM1136";
		break;
	case 0x7B37:
		type = "ARM11 MPCore";
		break;
	case 0x7B56:
		type = "ARM1156";
		break;
	case 0x7B76:
		arm11->arm.core_type = ARM_MODE_MON;
		/* NOTE: could default arm11->hardware_step to true */
		type = "ARM1176";
		break;
	default:
		LOG_ERROR("unexpected ARM11 ID code");
		return ERROR_FAIL;
	}
	LOG_INFO("found %s", type);

	/* unlikely this could ever fail, but ... */
	switch ((didr >> 16) & 0x0F) {
	case ARM11_DEBUG_V6:
	case ARM11_DEBUG_V61:		/* supports security extensions */
		break;
	default:
		LOG_ERROR("Only ARM v6 and v6.1 debug supported.");
		return ERROR_FAIL;
	}

	arm11->brp = ((didr >> 24) & 0x0F) + 1;

	/** \todo TODO: reserve one brp slot if we allow breakpoints during step */
	arm11->free_brps = arm11->brp;

	LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32,
			device_id, implementor, didr);

	/* as a side-effect this reads DSCR and thus
	 * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag
	 * as suggested by the spec.
	 */

	retval = arm11_check_init(arm11);
	if (retval != ERROR_OK)
		return retval;

	/* Build register cache "late", after target_init(), since we
	 * want to know if this core supports Secure Monitor mode.
	 */
	if (!target_was_examined(target))
		CHECK_RETVAL(arm11_dpm_init(arm11, didr));

	/* ETM on ARM11 still uses original scanchain 6 access mode */
	if (arm11->arm.etm && !target_was_examined(target)) {
		*register_get_last_cache_p(&target->reg_cache) =
			etm_build_reg_cache(target, &arm11->jtag_info,
					arm11->arm.etm);
		CHECK_RETVAL(etm_setup(target));
	}

	target_set_examined(target);

	return ERROR_OK;
}
Exemplo n.º 16
0
struct reg_cache *mips32_build_reg_cache(struct target *target)
{
	/* get pointers to arch-specific information */
	struct mips32_common *mips32 = target_to_mips32(target);

	int num_regs = MIPS32_NUM_REGS;
	struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
	struct reg_cache *cache = malloc(sizeof(struct reg_cache));
	struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
	struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);
	struct reg_feature *feature;
	int i;

	/* 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].num = mips32_regs[i].id;
		arch_info[i].target = target;
		arch_info[i].mips32_common = mips32;

		reg_list[i].name = mips32_regs[i].name;
		reg_list[i].size = 32;

		if (mips32_regs[i].flag == MIPS32_GDB_DUMMY_FP_REG) {
			reg_list[i].value = mips32_gdb_dummy_fp_value;
			reg_list[i].valid = 1;
			reg_list[i].arch_info = NULL;
			register_init_dummy(&reg_list[i]);
		} else {
			reg_list[i].value = calloc(1, 4);
			reg_list[i].valid = 0;
			reg_list[i].type = &mips32_reg_type;
			reg_list[i].arch_info = &arch_info[i];

			reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
			if (reg_list[i].reg_data_type)
				reg_list[i].reg_data_type->type = mips32_regs[i].type;
			else
				LOG_ERROR("unable to allocate reg type list");
		}

		reg_list[i].dirty = 0;

		reg_list[i].group = mips32_regs[i].group;
		reg_list[i].number = i;
		reg_list[i].exist = true;
		reg_list[i].caller_save = true;	/* gdb defaults to true */

		feature = calloc(1, sizeof(struct reg_feature));
		if (feature) {
			feature->name = mips32_regs[i].feature;
			reg_list[i].feature = feature;
		} else
			LOG_ERROR("unable to allocate feature list");
	}

	return cache;
}