Example #1
0
static void init_code_breakpoints(stlink_t *sl) {
	memset(sl->q_buf, 0, 4);
	stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/);
        printf("KARL - should read back as 0x03, not 60 02 00 00\n");
        stlink_read_debug32(sl, CM3_REG_FP_CTRL);

	for(int i = 0; i < CODE_BREAK_NUM; i++) {
		code_breaks[i].type = 0;
		stlink_write_debug32(sl, CM3_REG_FP_COMP0 + i * 4, 0);
	}
}
Example #2
0
static void init_data_watchpoints(stlink_t *sl) {
    DLOG("init watchpoints\n");

    // set trcena in debug command to turn on dwt unit
    stlink_write_debug32(sl, 0xE000EDFC,
            stlink_read_debug32(sl, 0xE000EDFC) | (1<<24));

    // make sure all watchpoints are cleared
    for(int i = 0; i < DATA_WATCH_NUM; i++) {
        data_watches[i].fun = WATCHDISABLED;
        stlink_write_debug32(sl, 0xe0001028 + i * 16, 0);
    }
}
Example #3
0
static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) {
	stm32_addr_t fpb_addr = addr & ~0x3;
	int type = addr & 0x2 ? CODE_BREAK_HIGH : CODE_BREAK_LOW;

	if(addr & 1) {
		fprintf(stderr, "update_code_breakpoint: unaligned address %08x\n", addr);
		return -1;
	}

	int id = -1;
	for(int i = 0; i < CODE_BREAK_NUM; i++) {
		if(fpb_addr == code_breaks[i].addr ||
			(set && code_breaks[i].type == 0)) {
			id = i;
			break;
		}
	}

	if(id == -1) {
		if(set) return -1; // Free slot not found
		else	return 0;  // Breakpoint is already removed
	}

	struct code_hw_breakpoint* brk = &code_breaks[id];

	brk->addr = fpb_addr;

	if(set) brk->type |= type;
	else	brk->type &= ~type;

	if(brk->type == 0) {
		#ifdef DEBUG
		printf("clearing hw break %d\n", id);
		#endif

		stlink_write_debug32(sl, 0xe0002008 + id * 4, 0);
	} else {
	        uint32_t mask = (brk->addr) | 1 | (brk->type << 30);

		#ifdef DEBUG
		printf("setting hw break %d at %08x (%d)\n",
			id, brk->addr, brk->type);
		printf("reg %08x \n",
			mask);
		#endif

		stlink_write_debug32(sl, 0xe0002008 + id * 4, mask);
	}

	return 0;
}
Example #4
0
static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len)
{
	int i = 0;
	uint32_t mask;

	// computer mask
	// find a free watchpoint
	// configure

	mask = -1;
	i = len;
	while(i) {
		i >>= 1;
		mask++;
	}

	if((mask != (uint32_t)-1) && (mask < 16)) {
		for(i = 0; i < DATA_WATCH_NUM; i++) {
			// is this an empty slot ?
			if(data_watches[i].fun == WATCHDISABLED) {
				#ifdef DEBUG
				printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len);
				#endif

				data_watches[i].fun = wf;
				data_watches[i].addr = addr;
				data_watches[i].mask = mask;

				// insert comparator address
				stlink_write_debug32(sl, 0xE0001020 + i * 16, addr);

				// insert mask
				stlink_write_debug32(sl, 0xE0001024 + i * 16, mask);

				// insert function
				stlink_write_debug32(sl, 0xE0001028 + i * 16, wf);

				// just to make sure the matched bit is clear !
				stlink_read_debug32(sl,  0xE0001028 + i * 16);
				return 0;
			}
		}
	}

	#ifdef DEBUG
	printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len);
	#endif
	return -1;
}
Example #5
0
static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr)
{
    int i;

    for(i = 0 ; i < DATA_WATCH_NUM; i++) {
        if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) {
            DLOG("delete watchpoint %d addr %x\n", i, addr);

            data_watches[i].fun = WATCHDISABLED;
            stlink_write_debug32(sl, 0xe0001028 + i * 16, 0);

            return 0;
        }
    }

    DLOG("failure: delete watchpoint addr %x\n", addr);

    return -1;
}