This is an automated email from Gerrit.

Salvador Arroyo ([email protected]) just uploaded a new patch set to Gerrit, 
which you can find at http://openocd.zylin.com/4124

-- gerrit

commit bca0c9d627766acfeb67c19aa36bc7cdac9b3d04
Author: Salvador Arroyo <[email protected]>
Date:   Mon May 8 09:44:50 2017 +0200

    mips32: add micromips breakpoints support
    
    Breakpoint setting based on length (kind) only.
    Added 16bit aligned 32bit software breakpoints
    support and same filtering before setting
    breakpoint.
    Set the required isa bit in hardware breakpoints.
    Drop the isa bit in software breakpoints.
    
    Change-Id: I7020f27be16015194b76f385d9b8e5af496d0dfc
    Signed-off-by: Salvador Arroyo <[email protected]>

diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 8792310..7d1c06c 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -631,6 +631,11 @@ static int mips_m4k_set_breakpoint(struct target *target,
                comparator_list[bp_num].used = 1;
                comparator_list[bp_num].bp_value = breakpoint->address;
 
+               if (breakpoint->length != 4)                    /* make sure 
isa bit set */
+                       comparator_list[bp_num].bp_value |= 1;
+               else                                            /* make sure 
isa bit cleared */
+                       comparator_list[bp_num].bp_value &= ~1;
+
                /* EJTAG 2.0 uses 30bit IBA. First 2 bits are reserved.
                 * Warning: there is no IB ASID registers in 2.0.
                 * Do not set it! :) */
@@ -648,41 +653,77 @@ static int mips_m4k_set_breakpoint(struct target *target,
                                  bp_num, comparator_list[bp_num].bp_value);
        } else if (breakpoint->type == BKPT_SOFT) {
                LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
-               if (breakpoint->length == 4) {
+
+               uint32_t isa_req = breakpoint->length & 1;      /* micro mips 
request bit */
+               uint32_t bplength = breakpoint->length & ~1;    /* drop micro 
mips request bit for length */
+               uint32_t bpaddr = breakpoint->address & ~1;     /* drop isa bit 
from address, if set */
+
+               if (bplength == 4) {
                        uint32_t verify = 0xffffffff;
+                       uint32_t sdbbp32_instr = MIPS32_SDBBP(isa_req);
+                       if (ejtag_info->endianness && isa_req)
+                               sdbbp32_instr = SWAP16(sdbbp32_instr);
 
-                       retval = target_read_memory(target, 
breakpoint->address, breakpoint->length, 1,
-                                       breakpoint->orig_instr);
-                       if (retval != ERROR_OK)
-                               return retval;
-                       retval = target_write_u32(target, breakpoint->address, 
MIPS32_SDBBP(ejtag_info->isa));
-                       if (retval != ERROR_OK)
-                               return retval;
+                       if ((breakpoint->address & 3) == 0) {   /* word 
alligned */
 
-                       retval = target_read_u32(target, breakpoint->address, 
&verify);
-                       if (retval != ERROR_OK)
-                               return retval;
-                       if (verify != MIPS32_SDBBP(ejtag_info->isa)) {
-                               LOG_ERROR("Unable to set 32-bit breakpoint at 
address " TARGET_ADDR_FMT
-                                               " - check that memory is 
read/writable", breakpoint->address);
+                               retval = target_read_memory(target, bpaddr, 
bplength, 1, breakpoint->orig_instr);
+                               if (retval != ERROR_OK)
+                                       return retval;
+
+                               retval = target_write_u32(target, bpaddr, 
sdbbp32_instr);
+                               if (retval != ERROR_OK)
+                                       return retval;
+
+                               retval = target_read_u32(target, bpaddr, 
&verify);
+                               if (retval != ERROR_OK)
+                                       return retval;
+
+                               if (verify != sdbbp32_instr)
+                                       verify = 0;
+
+                       } else {        /* 16 bit aligned */
+                               retval = target_read_memory(target, bpaddr, 2, 
2, breakpoint->orig_instr);
+                               if (retval != ERROR_OK)
+                                       return retval;
+
+                               uint8_t sdbbp_buf[4];
+                               target_buffer_set_u32(target, sdbbp_buf, 
sdbbp32_instr);
+
+                               retval = target_write_memory(target, bpaddr, 2, 
2, sdbbp_buf);
+                               if (retval != ERROR_OK)
+                                       return retval;
+
+                               retval = target_read_memory(target, bpaddr, 2, 
2, sdbbp_buf);
+                               if (retval != ERROR_OK)
+                                       return retval;
+
+                               if (target_buffer_get_u32(target, sdbbp_buf) != 
sdbbp32_instr)
+                                       verify = 0;
+                       }
+
+                       if (verify == 0) {
+                               LOG_ERROR("Unable to set 32bit breakpoint at 
address %08" PRIx64
+                                       " - check that memory is 
read/writable", breakpoint->address);
                                return ERROR_OK;
                        }
+
                } else {
                        uint16_t verify = 0xffff;
 
-                       retval = target_read_memory(target, 
breakpoint->address, breakpoint->length, 1,
-                                       breakpoint->orig_instr);
+                       retval = target_read_memory(target, bpaddr, bplength, 
1, breakpoint->orig_instr);
                        if (retval != ERROR_OK)
                                return retval;
-                       retval = target_write_u16(target, breakpoint->address, 
MIPS16_SDBBP(ejtag_info->isa));
+
+                       retval = target_write_u16(target, bpaddr, 
MIPS16_SDBBP(isa_req));
                        if (retval != ERROR_OK)
                                return retval;
 
-                       retval = target_read_u16(target, breakpoint->address, 
&verify);
+                       retval = target_read_u16(target, bpaddr, &verify);
                        if (retval != ERROR_OK)
                                return retval;
-                       if (verify != MIPS16_SDBBP(ejtag_info->isa)) {
-                               LOG_ERROR("Unable to set 16-bit breakpoint at 
address " TARGET_ADDR_FMT
+
+                       if (verify != MIPS16_SDBBP(isa_req)) {
+                               LOG_ERROR("Unable to set 16bit breakpoint at 
address %08" PRIx64
                                                " - check that memory is 
read/writable", breakpoint->address);
                                return ERROR_OK;
                        }
@@ -725,46 +766,58 @@ static int mips_m4k_unset_breakpoint(struct target 
*target,
 
        } else {
                /* restore original instruction (kept in target endianness) */
+               uint32_t isa_req = breakpoint->length & 1;
+               uint32_t bplength = breakpoint->length & ~1;
+               uint8_t current_instr[4];
                LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
-               if (breakpoint->length == 4) {
-                       uint32_t current_instr;
-
-                       /* check that user program has not modified breakpoint 
instruction */
-                       retval = target_read_memory(target, 
breakpoint->address, 4, 1,
-                                       (uint8_t *)&current_instr);
-                       if (retval != ERROR_OK)
-                               return retval;
-
-                       /**
-                        * target_read_memory() gets us data in _target_ 
endianess.
-                        * If we want to use this data on the host for 
comparisons with some macros
-                        * we must first transform it to _host_ endianess using 
target_buffer_get_u32().
-                        */
-                       current_instr = target_buffer_get_u32(target, (uint8_t 
*)&current_instr);
-
-                       if (current_instr == MIPS32_SDBBP(ejtag_info->isa)) {
-                               retval = target_write_memory(target, 
breakpoint->address, 4, 1,
-                                               breakpoint->orig_instr);
+               if (bplength == 4) {
+                       uint32_t sdbbp32_instr =  MIPS32_SDBBP(isa_req);
+                       if (ejtag_info->endianness && isa_req)
+                               sdbbp32_instr = SWAP16(sdbbp32_instr);
+
+                       if ((breakpoint->address & 3) == 0) {           /* 
32bit aligned */
+                               /* check that user program has not modified 
breakpoint instruction */
+                               retval = target_read_memory(target, 
breakpoint->address, 4, 1, current_instr);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                               /**
+                               * target_read_memory() gets us data in _target_ 
endianess.
+                               * If we want to use this data on the host for 
comparisons with some macros
+                               * we must first transform it to _host_ 
endianess using target_buffer_get_u16().
+                               */
+                               if (sdbbp32_instr == 
target_buffer_get_u32(target, current_instr)) {
+                                       retval = target_write_memory(target, 
breakpoint->address, 4, 1,
+                                                                               
breakpoint->orig_instr);
+                                       if (retval != ERROR_OK)
+                                               return retval;
+                               }
+                       } else {        /* 16bit alligned */
+                               retval = target_read_memory(target, 
breakpoint->address, 2, 2, current_instr);
                                if (retval != ERROR_OK)
                                        return retval;
+
+                               if (sdbbp32_instr == 
target_buffer_get_u32(target, current_instr)) {
+                                       retval = target_write_memory(target, 
breakpoint->address, 2, 2,
+                                                                               
breakpoint->orig_instr);
+                                       if (retval != ERROR_OK)
+                                               return retval;
+                               }
                        }
                } else {
-                       uint16_t current_instr;
-
                        /* check that user program has not modified breakpoint 
instruction */
-                       retval = target_read_memory(target, 
breakpoint->address, 2, 1,
-                                       (uint8_t *)&current_instr);
+                       retval = target_read_memory(target, 
breakpoint->address, 2, 1, current_instr);
                        if (retval != ERROR_OK)
                                return retval;
-                       current_instr = target_buffer_get_u16(target, (uint8_t 
*)&current_instr);
-                       if (current_instr == MIPS16_SDBBP(ejtag_info->isa)) {
+
+                       if (target_buffer_get_u16(target, current_instr) == 
MIPS16_SDBBP(isa_req)) {
                                retval = target_write_memory(target, 
breakpoint->address, 2, 1,
-                                               breakpoint->orig_instr);
+                                                                       
breakpoint->orig_instr);
                                if (retval != ERROR_OK)
                                        return retval;
                        }
                }
        }
+
        breakpoint->set = 0;
 
        return ERROR_OK;
@@ -774,6 +827,12 @@ static int mips_m4k_add_breakpoint(struct target *target, 
struct breakpoint *bre
 {
        struct mips32_common *mips32 = target_to_mips32(target);
 
+       if ((breakpoint->length > 5 || breakpoint->length < 2) ||               
/* out of range */
+               (breakpoint->length == 4 && (breakpoint->address & 2)) ||       
/* mips32 unaligned */
+               (mips32->isa_imp == MIPS32_ONLY && breakpoint->length != 4) ||  
/* misp32 specific */
+               ((mips32->isa_imp & 1) != (breakpoint->length & 1)))            
/* isa not implemented */
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+
        if (breakpoint->type == BKPT_HARD) {
                if (mips32->num_inst_bpoints_avail < 1) {
                        LOG_INFO("no hardware breakpoint available");

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to