Bug 25211 - sim: m68hc11: fails to remap registers when writing INIT
Summary: sim: m68hc11: fails to remap registers when writing INIT
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: sim (show other bugs)
Version: 8.3.1
: P2 normal
Target Milestone: ---
Assignee: Mike Frysinger
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-11-21 09:47 UTC by Sebastien F4GRX
Modified: 2023-01-12 15:41 UTC (History)
1 user (show)

See Also:
Host:
Target: m68hc11-elf
Build:
Last reconfirmed: 2022-11-09 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sebastien F4GRX 2019-11-21 09:47:12 UTC
Hello

I am using gdb-8.3.1 built with --target=m68hc11-elf

My code is pure hand written assembly with no frame pointer.

The first opcodes of my program are remapping the HC11 registers to address zero (instead of hardware default 0x1000) using the following hc11 opcodes:

.equ INIT 0x3D
ldaa #0
staa INIT+0x1000

Resulting in valid machine code:

4f
b7 10 3d

This works in a real hc11.

However, m68hc11-elf-run produces the following result:

$ m68hc11-elf-run monitor.elf
/m68hc11: hw_attach_address: no parent attach method
program stopped with signal 6 (Aborted).

The output in m68hc11-elf-gdb with target sim is identical.

I recompiled gdb with -O0 and -g and managed to trace the issue to the function m68hc11cpu_io_write in file sim/m68hc11/dv-m68hc11.c

at line 1032, the function hw_detach_address is called with first parameter hw_parent(me). Same at line 1038, hw_attach_address is called with the same first parameter.

I have noticed that my program runs when I replace this first parameter by me instead of hw_parent(me).

After making this change, my program is perfectly simulated. Single step does not seem to work correctly but that's another issue, and direct execution works.


So here is a trivial patch that fixes this bug:

diff -r gdb-8.3.1/sim/m68hc11/dv-m68hc11.c gdb-8.3.1-fixed/sim/m68hc11/dv-m68hc11.c
1032c1032
<             hw_detach_address (hw_parent (me), M6811_IO_LEVEL,
---
>             hw_detach_address (me, M6811_IO_LEVEL,
1038c1038
<             hw_attach_address (hw_parent (me), M6811_IO_LEVEL,
---
>             hw_attach_address (me, M6811_IO_LEVEL,

Could that be confirmed and fixed in the next version of gdb?

Sorry if my report is unusual, this is the first time I'm doing this.

Thank you.
Comment 1 Mike Frysinger 2021-01-11 06:54:09 UTC
Thanks for the patch.
Please follow the contribution instructions to have it reviewed:
https://sourceware.org/gdb/wiki/ContributionChecklist
Comment 2 Sebastien F4GRX 2021-01-12 08:32:24 UTC
I'm not doing ALL OF THIS for a trivial two-liner.

I release all my rights to this contributions if you want to include it on your own name.

meanwhile

-I recoded a fully working hc11 simulator
-People needing this will find the issue and the fix via a web search.
Comment 3 Mike Frysinger 2022-11-08 08:50:35 UTC
sorry, but that's not how any of this works.  sending an e-mail with a patch attached is less effort than filing a bug report when using git.

that said, i don't think your patch is correct.  no other device model calls hw_{attach,detach}_address like that.  i'm guessing the sim_hw setup logic in interp.c needs fixing.
Comment 4 Mike Frysinger 2022-11-09 14:50:51 UTC
i double checked gdb-7.1 (which was released over a decade ago) and it seems to fail in the same way, so def not a regression.  i didn't look back further since even that version required backporting/hacking things up to get it to build with current toolchain versions.

to repro:
$ ./configure --target=m68hc11-elf
$ make all-sim
$ cat >test.s <<EOF
.equ INIT, 0x3D
ldaa #0
staa INIT+0x1000
EOF
$ ./gas/as-new test.s -o test.o
$ ./ld/ld-new test.o -o test
$ ./sim/m68hc11/run ./test
/m68hc11: hw_attach_address: no parent attach method
program stopped with signal 6 (Aborted).
Comment 5 Sebastien F4GRX 2022-11-09 15:17:52 UTC
Hello,

I really appreciate that you managed to produce a minimal test case to reproduce the bug. I should have done that.

TBH it's quite hard for me to contribute here because there are so many rules in places that I feel overwhelmed and dont know how to start. There is also a LOT of legacy in these complex code bases and even if I could hack something that worked, I have absolutely no idea how to fix this properly. Meanwhile, I have coded my own simulator where this function works.

Setting init to zero is quite important in the 68hc11, because in extended mode, when you intend to use the hc11 as an almost generic microprocessor (not just with a small embedded task), then the default value of INIT means that the IO range lies in the middle of any large external ram you install on the bus.

I am very grateful that you have identified the issue. I dont know how to fix it but I DEFINITELY volunteer to test it.

Sebastien
Comment 6 Mike Frysinger 2022-11-10 15:05:17 UTC
hmm, i poked it more today, and now i wonder if this is a bug in dv-core.  looking through the codebase, m68hc11 seems to have the only device models that ever actually call hw_detach_address which might be why no one noticed before.

practically speaking, it does the samething as your proposed patch because the dv-m68hc11 detach method calls sim_core_detach.  but i think the right fix is to change dv-core so it has mirror attach/detach logic.

i'll probably send this out after GDB 13 branches.

--- a/sim/common/dv-core.c       
+++ b/sim/common/dv-core.c
@@ -72,6 +72,23 @@ dv_core_attach_address_callback (struct hw *me,
 }
 
 
+static void
+dv_core_detach_address_callback (struct hw *me,
+                int level,
+                int space,
+                address_word addr,
+                address_word nr_bytes,
+                struct hw *client)
+{
+  HW_TRACE ((me, "detach - level=%d, space=%d, addr=0x%lx, nr_bytes=%ld, client=%s",
+        level, space, (unsigned long) addr, (unsigned long) nr_bytes, hw_path (client)));
+  /* NOTE: At preset the space is assumed to be zero.  Perhaphs the
+     space should be mapped onto something for instance: space0 -
+     unified memory; space1 - IO memory; ... */
+  sim_core_detach (hw_system (me), NULL, /*cpu*/ level, space, addr);
+}                                       
+
+
 static unsigned
 dv_core_dma_read_buffer_callback (struct hw *me,
                  void *dest,    
@@ -109,6 +126,7 @@ static void   
 dv_core_finish (struct hw *me)  
 {                               
   set_hw_attach_address (me, dv_core_attach_address_callback);
+  set_hw_detach_address (me, dv_core_detach_address_callback);
   set_hw_dma_write_buffer (me, dv_core_dma_write_buffer_callback);
   set_hw_dma_read_buffer (me, dv_core_dma_read_buffer_callback);
 }
Comment 7 Mike Frysinger 2022-12-20 01:32:04 UTC
pushed post gdb-13 branch
Comment 8 Sebastien F4GRX 2023-01-12 15:41:20 UTC
Hi,

I have tested binutils main branch, which includes your fix, and I can confirm that the hc11 simulator now remaps the IO registers when INIT is modified.

Thank you very much for this fix.

Sebastien