Fix for setting/clearing breaks take 2
John Newlin
jnewlin@rawbw.com
Tue May 25 03:53:00 GMT 2004
Jonathan Larmour wrote:
> John Newlin wrote:
>
>> My previous patch had a small bug in it. It really works this time. ;)
>
>
> Can you give a bit more background on this? This patch doesn't seem
> right to me.... surely you should be defining things so that
> "*(t_inst*)pc = (t_inst)HAL_BREAKINST;" will work?
Unfortunately that does not work on the Xtensa architecture. Xtensa has
instructions that are 2 bytes or 3 bytes. The break instruction is
2-bytes, however it can be on any alignment (due to the intermixed
3-byte instructions throwing off the alignment). Yes, the architecture
is weird that way, instructions can be on any alignment, but the
load/store instructions require aligned data. It does make for some
compact code though. :)
>
> If there is a problem setting the breakpoint due to something not
> being aligned appropriately, then the __read/write_mem_safe will not
> necessarily have completed.
Those functions check alignment, and for something byte aligned will do
byte read/writes. Much like memcpy. A friend suggested this might be
better:
break_buffer.savedInstr = cyg_hal_gdb_insert_breakinst(pc);
>
> Can you tell me what the size of HAL_BREAKINST is? And the alignment
> requirements?
It's 2 bytes, but can fall on any alignment.
>
> Jifl
>
>> ------------------------------------------------------------------------
>>
>> Index: hal/common/current/ChangeLog
>> ===================================================================
>> RCS file: /cvs/ecos/ecos/packages/hal/common/current/ChangeLog,v
>> retrieving revision 1.103
>> diff -c -r1.103 ChangeLog
>> *** hal/common/current/ChangeLog 22 Apr 2004 15:26:33 -0000 1.103
>> --- hal/common/current/ChangeLog 21 May 2004 22:18:31 -0000
>> ***************
>> *** 1,3 ****
>> --- 1,13 ----
>> + 2004-05-19 John Newlin <jnewlin@stretchinc.com>
>> + + * src/hal_stub.c:
>> + (cyg_hal_gdb_interrupt) + (cyg_hal_gdb_remove_break):
>> Changed both to use
>> + _read_mem_safe/__write_mem_safe for inserting a breakpoint, and
>> + restoring the original instruction.
>> + The Xtensa architecture (and others maybe?) can have unaligned
>> + instructions, which caused unaligned load/store exception.
>> +
>> 2004-04-22 Jani Monoses <jani@iv.ro>
>> * cdl/hal.cdl :
>> Index: hal/common/current/src/hal_stub.c
>> ===================================================================
>> RCS file: /cvs/ecos/ecos/packages/hal/common/current/src/hal_stub.c,v
>> retrieving revision 1.38
>> diff -c -r1.38 hal_stub.c
>> *** hal/common/current/src/hal_stub.c 6 May 2003 21:00:20 -0000
>> 1.38
>> --- hal/common/current/src/hal_stub.c 21 May 2004 22:18:31 -0000
>> ***************
>> *** 281,286 ****
>> --- 281,288 ----
>> void cyg_hal_gdb_interrupt (target_register_t pc)
>> {
>> + t_inst break_inst = HAL_BREAKINST;
>> + CYGARC_HAL_SAVE_GP();
>> // Clear flag that we Continued instead of Stepping
>> ***************
>> *** 290,298 ****
>> cyg_hal_gdb_remove_break(
>> (target_register_t)break_buffer.targetAddr );
>> if (NULL == break_buffer.targetAddr) {
>> ! break_buffer.targetAddr = (t_inst*) pc;
>> ! break_buffer.savedInstr = *(t_inst*)pc;
>> ! *(t_inst*)pc = (t_inst)HAL_BREAKINST;
>> __data_cache(CACHE_FLUSH);
>> __instruction_cache(CACHE_FLUSH);
>> --- 292,306 ----
>> cyg_hal_gdb_remove_break(
>> (target_register_t)break_buffer.targetAddr );
>> if (NULL == break_buffer.targetAddr) {
>> ! // Not always safe to read/write directly to program
>> ! // memory due to possibly unaligned instruction, use the
>> ! // provided memory functions instead.
>> ! __read_mem_safe(&break_buffer.savedInstr, (t_inst*)pc,
>> HAL_BREAKINST_SIZE);
>> ! __write_mem_safe(&break_inst, (t_inst*)pc, HAL_BREAKINST_SIZE);
>> ! ! // Save the PC where we put the break, so we can remove
>> ! // it after the target takes the break.
>> ! break_buffer.targetAddr = (t_inst*)pc;
>> __data_cache(CACHE_FLUSH);
>> __instruction_cache(CACHE_FLUSH);
>> ***************
>> *** 308,314 ****
>> return 0;
>> if ((t_inst*)pc == break_buffer.targetAddr) {
>> ! *(t_inst*)pc = break_buffer.savedInstr;
>> break_buffer.targetAddr = NULL;
>> __data_cache(CACHE_FLUSH);
>> --- 316,323 ----
>> return 0;
>> if ((t_inst*)pc == break_buffer.targetAddr) {
>> ! ! __write_mem_safe(&break_buffer.savedInstr, (t_inst*)pc,
>> HAL_BREAKINST_SIZE);
>> break_buffer.targetAddr = NULL;
>> __data_cache(CACHE_FLUSH);
>
>
>
More information about the Ecos-patches
mailing list