SparkFun Forums 

Where electronics enthusiasts find answers.

Open source ARM Debugger
By fatalfeel
#187098
//debug source section
static void pl2303_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct pl2303_gpio *gpio = to_pl2303_gpio(chip);
struct pl2303_gpio_desc *desc;

mutex_lock(&gpio->lock);
desc = gpio->descs + offset;
if (value) //--->break here
gpio->data[desc->value_offset] |= desc->value_mask;
else
gpio->data[desc->value_offset] &= ~desc->value_mask;

pl2303_vendor_write(desc->value_ctrl, gpio->data[desc->value_offset], gpio->serial);

mutex_unlock(&gpio->lock);
}

////////////////////////////////////////openocd
/root/project_board/free_imx/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-gdb
(gdb) target remote localhost:3333
(gdb) symbol-file /root/project_board/free_imx/out/matrix_io/kernel/vmlinux
(gdb) mon halt
(gdb) break /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:297
(gdb) continue
Breakpoint 1, pl2303_gpio_set (chip=0x800719bc, offset=3159793204, value=-2114730436)
at /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:297
297 if (value)
(gdb) p value
$7 = -2114730436

Breakpoint 1, pl2303_vendor_write (value=65535, index=65535, serial=0x0)
at /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:218
218 return res;
(gdb) p &index
$1 = (__u16 *) 0xbccb9d9c
(gdb) p &value
$2 = (__u16 *) 0xbccb9d9e
(gdb) p &res
$3 = (int *) 0xbccb9dac

https://picasaweb.google.com/1061855410 ... 8164287378
////////////////////////////////////////
//////////////////////////////////////KGDB
(gdb) target remote /dev/ttyUSB0
Remote debugging using /dev/ttyUSB0
kgdb_breakpoint ()
at /root/project_board/free_imx/myandroid/kernel_imx/kernel/debug/debug_core.c:1025
1025 arch_kgdb_breakpoint();
(gdb) break /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:297
Breakpoint 1 at 0x8075bfd0: file /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c, line 297.
(gdb) continue
Continuing.
Breakpoint 1, pl2303_gpio_set (chip=0xbc5e99e4, offset=0, value=0)
at /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:297
(gdb) p value
$1 = 0

Breakpoint 1, pl2303_vendor_write (value=1, index=48, serial=0xbc5d7980)
at /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:218
218 return res;
(gdb) p &index
$10 = (__u16 *) 0xbccb9d9c
(gdb) p &value
$11 = (__u16 *) 0xbccb9d9e
(gdb) p &res
$12 = (int *) 0xbccb9dac

https://picasaweb.google.com/1061855410 ... 7029124338
/////////////////////////////////////////////////////////////////////////
value = 0 is correct on kgdb
openocd and kgdb symbol address are the same

openocd global variable is good, only local variable is wrong. can fixed it?

and call stack jsut can see 2 or 3 layer.
kgdb can read all struct variable and call stacks
can make openocd like kgdb?

bug similar as this but not sure~~~how to fix openocd
https://code.google.com/p/go/issues/detail?id=8256
Last edited by fatalfeel on Fri Jan 08, 2016 6:15 pm, edited 11 times in total.
By fatalfeel
#187144
i compare global and local variable in openocd
static int gdb_read_memory_packet(struct connection *connection, char const *packet, int packet_size)
...
...
...
...

into cortex_a_read_phys_memory

get value is wrong on local variable

any idea for me?
By fatalfeel
#187261
I write local variable 0x03, address=0x4ccd7d86, buffer={0x03, 0x00}
retval = cortex_a_write_phys_memory(target, address, size, count, buffer);


then Read local variable, address= 0x4ccd7d86
retval = cortex_a_read_phys_memory(target, address, size, count, buffer);

buffer = {0x03,0x00}

the value is 0x03 is ok~~~

get local variable still wrong
By fatalfeel
#187264
static int cortex_a_read_memory(struct target *target,
uint32_t address,
uint32_t size,
uint32_t count,
uint8_t *buffer)

{
int mmu_enabled = 0;
//uint32_t virt, phys;
int retval;
struct armv7a_common* armv7a = target_to_armv7a(target);
//struct adiv5_dap* swjdp = armv7a->arm.dap;
//uint8_t apsel = swjdp->apsel;


/* cortex_a handles unaligned memory access */

LOG_DEBUG("Reading memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address, size, count);


/* determine if MMU was enabled on target stop */

if (!armv7a->is_armv7r)

{

retval = cortex_a_mmu(target, &mmu_enabled);

if (retval != ERROR_OK)

return retval;

}


/////when I mark this section the local pointer variable is correct, but local variable is wrong too
////
////
/*if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap))
{
if (mmu_enabled)
{
virt = address;

retval = cortex_a_virt2phys(target, virt, &phys);

if (retval != ERROR_OK)
return retval;

LOG_DEBUG("Reading at virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32, virt, phys);

address = phys;
}

retval = cortex_a_read_phys_memory(target, address, size, count, buffer);
}
else*/
{

if (mmu_enabled)

{

retval = cortex_a_check_address(target, address);


if (retval != ERROR_OK)

return retval;

/* enable MMU as we could have disabled it for phys access */

retval = cortex_a_mmu_modify(target, 1);


if (retval != ERROR_OK)

return retval;

}


retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);

}


return retval;

}
Last edited by fatalfeel on Tue Jan 12, 2016 7:15 pm, edited 1 time in total.
By fatalfeel
#187296
Fixed~~~~~~~~~~~~~~~~
use APB read/write memory

if one time fast read, first 4 bytes are correct, but others are wrong
use slow path read can fix it

demo photo:
1. https://picasaweb.google.com/1061855410 ... 1048247058
2. https://picasaweb.google.com/1061855410 ... 9468163938
3. https://picasaweb.google.com/1061855410 ... 4608161106

Detail:
http://fatalfeel.blogspot.tw/2015/12/op ... el-of.html


//////////////////////////
gedit /root/openocd-0.9.0/src/target/target.c
static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer)
{
int retval;
int remain;
unsigned int one_unit;
unsigned int length;
unsigned int ptr_shift;

retval = -1;
ptr_shift = 0;
remain = count;

if( address > 0 )
{
while( remain > 0 )
{
if( remain >= (int)sizeof(uint32_t) )
{
one_unit = sizeof(uint32_t);
length = remain/sizeof(uint32_t);
}
else if( remain >= (int)sizeof(uint16_t) )
{
one_unit = sizeof(uint16_t);
length = remain/sizeof(uint16_t);
}
else
{
one_unit = sizeof(uint8_t);
length = remain/sizeof(uint8_t);
}

retval = target_read_memory(target, address+ptr_shift, one_unit, length, buffer+ptr_shift);

if (retval != ERROR_OK)
break;

ptr_shift += one_unit * length;
remain -= one_unit * length;
} //end while
}

return retval;
}

////////
in static int cortex_a_examine_first(struct target *target)
retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7a->memory_ap);
//modify to
retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv7a->memory_ap);

////////
//Use slow path
gedit /root/openocd-0.9.0/src/target/cortex_a.c
//in cortex_a_read_apb_ab_memory
if (size == 4 && (address % 4) == 0)
//change to
if( 0 )
By fatalfeel
#187428
http://arttools.blogspot.tw/2009/09/deb ... ystem.html

For configuring systems at start up, such as setting memory controller parameters, clocks and PLL registers, memory access through the AHB access port is good. This should also work well for writing to flash memories.

For debugging code running on the MPU, the APB and access through the MPU core probably should be used, since this method avoids problems with virtual to physical address translations and also helps avoid cache coherency problems.
By fatalfeel
#187435
in armv7a.c
struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm *arm = &armv7a->arm;

if (armv7a->common_magic != ARMV7_COMMON_MAGIC) {
LOG_ERROR("BUG: called for a non-ARMv7A target");
return ERROR_COMMAND_SYNTAX_ERROR;
}

arm_arch_state(target);

if (armv7a->is_armv7r) {
LOG_USER("D-Cache: %s, I-Cache: %s",
state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled],
state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]);
} else {
LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
state[armv7a->armv7a_mmu.mmu_enabled],
state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled],
state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]);
}

we can do the auto judgement for cortex_a_examine_first(struct target *target)
I prefer this way than dap apsel in cfg
because u need change dap apsel 0 or dap apsel 1

in static int cortex_a_post_debug_entry(struct target *target)
after
cortex_a->curr_mode = armv7a->arm.core_mode;
add
armv7a->memory_ap = armv7a->armv7a_mmu.mmu_enabled;
will auto select right bus~

when mmu_enabled On is debug linux kernel core
when mmu_enabled Off is debug uboot code upload on Hardware pin boot Mode0