All of lore.kernel.org
 help / color / mirror / Atom feed
* Point where target instructions are read
@ 2024-04-01 19:50 Gautam Bhat
  2024-04-01 20:31 ` Richard Henderson
  0 siblings, 1 reply; 10+ messages in thread
From: Gautam Bhat @ 2024-04-01 19:50 UTC (permalink / raw)
  To: QEMU Developers

Hi,

Some background: I am trying to write a CPU emulator for MSP430 with
Qemu. I am loading the MSP430 program as follows using the generic
device loader:

/qemu-system-msp430 -machine msp430-launchpad -device
loader,file=simple_test -d in_asm,out_asm

I have implemented somewhat the TranslatorOps callbacks and my sample
output with some prints is as follows:

===msp430_tr_disas_log:204===

OUT: [size=51]
 -- guest addr 0x00000000000007fa + tb prologue
0x7fff6403fe00:  8b 5d f0                 movl     -0x10(%rbp), %ebx
0x7fff6403fe03:  85 db                    testl    %ebx, %ebx
0x7fff6403fe05:  0f 8c 1c 00 00 00        jl       0x7fff6403fe27
0x7fff6403fe0b:  c6 45 f4 01              movb     $1, -0xc(%rbp)
0x7fff6403fe0f:  e9 00 00 00 00           jmp      0x7fff6403fe14
0x7fff6403fe14:  c7 45 00 fc 07 00 00     movl     $0x7fc, (%rbp)
0x7fff6403fe1b:  48 8d 05 1e ff ff ff     leaq     -0xe2(%rip), %rax
0x7fff6403fe22:  e9 f1 01 fc ff           jmp      0x7fff64000018
0x7fff6403fe27:  48 8d 05 15 ff ff ff     leaq     -0xeb(%rip), %rax
0x7fff6403fe2e:  e9 e5 01 fc ff           jmp      0x7fff64000018

===gen_intermediate_code:251===
===msp430_tr_init_disas_context:84===
===msp430_tr_tb_start:99===
===msp430_tr_insn_start:107===
===msp430_tr_translate_insn:122===
CTX Dump State
==============
pc_first 2044
pc_next 2044
is_jmp 0
max_insns 1
num_insns 1
TB flags: 1
TB cflags: 4278190081
TB CS base: 0
TB PC: 2044
==============
Opcode: 0
is_jmp: 1
DISAS_TOO_MANY ===msp430_tr_tb_stop:170===

I was trying to find out where exactly in the Qemu code does it read
the target instructions from the file loaded (I could trace it to
load_elf(...) loading the FW file) and call my TranslatorOps
callbacks.  I get the above output continuously in a loop. Also when
the device generic loader is used, should I set the program counter to
a specific value?

I am not able to understand how to proceed. Any help would be greatly
appreciated.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Point where target instructions are read
  2024-04-01 19:50 Point where target instructions are read Gautam Bhat
@ 2024-04-01 20:31 ` Richard Henderson
  2024-04-03 18:15   ` Gautam Bhat
  0 siblings, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2024-04-01 20:31 UTC (permalink / raw)
  To: Gautam Bhat, QEMU Developers

On 4/1/24 09:50, Gautam Bhat wrote:
> Hi,
> 
> Some background: I am trying to write a CPU emulator for MSP430 with
> Qemu. I am loading the MSP430 program as follows using the generic
> device loader:
> 
> /qemu-system-msp430 -machine msp430-launchpad -device
> loader,file=simple_test -d in_asm,out_asm
> 
> I have implemented somewhat the TranslatorOps callbacks and my sample
> output with some prints is as follows:
> 
> ===msp430_tr_disas_log:204===
> 
> OUT: [size=51]
>   -- guest addr 0x00000000000007fa + tb prologue
> 0x7fff6403fe00:  8b 5d f0                 movl     -0x10(%rbp), %ebx
> 0x7fff6403fe03:  85 db                    testl    %ebx, %ebx
> 0x7fff6403fe05:  0f 8c 1c 00 00 00        jl       0x7fff6403fe27
> 0x7fff6403fe0b:  c6 45 f4 01              movb     $1, -0xc(%rbp)
> 0x7fff6403fe0f:  e9 00 00 00 00           jmp      0x7fff6403fe14
> 0x7fff6403fe14:  c7 45 00 fc 07 00 00     movl     $0x7fc, (%rbp)
> 0x7fff6403fe1b:  48 8d 05 1e ff ff ff     leaq     -0xe2(%rip), %rax
> 0x7fff6403fe22:  e9 f1 01 fc ff           jmp      0x7fff64000018
> 0x7fff6403fe27:  48 8d 05 15 ff ff ff     leaq     -0xeb(%rip), %rax
> 0x7fff6403fe2e:  e9 e5 01 fc ff           jmp      0x7fff64000018
> 
> ===gen_intermediate_code:251===
> ===msp430_tr_init_disas_context:84===
> ===msp430_tr_tb_start:99===
> ===msp430_tr_insn_start:107===
> ===msp430_tr_translate_insn:122===
> CTX Dump State
> ==============
> pc_first 2044
> pc_next 2044
> is_jmp 0
> max_insns 1
> num_insns 1
> TB flags: 1
> TB cflags: 4278190081
> TB CS base: 0
> TB PC: 2044
> ==============
> Opcode: 0
> is_jmp: 1
> DISAS_TOO_MANY ===msp430_tr_tb_stop:170===
> 
> I was trying to find out where exactly in the Qemu code does it read
> the target instructions from the file loaded (I could trace it to
> load_elf(...) loading the FW file)

Yes, the contents of the file are loaded within load_elf().


> and call my TranslatorOps
> callbacks.  I get the above output continuously in a loop. Also when
> the device generic loader is used, should I set the program counter to
> a specific value?

The boot process must cooperate somehow.

When using loader, you must link the image such that it loads at the pc reset address 
defined by the architecture manual.


r~


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Point where target instructions are read
  2024-04-01 20:31 ` Richard Henderson
@ 2024-04-03 18:15   ` Gautam Bhat
  2024-04-03 22:35     ` BALATON Zoltan
  2024-04-03 22:40     ` Richard Henderson
  0 siblings, 2 replies; 10+ messages in thread
From: Gautam Bhat @ 2024-04-03 18:15 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Tue, Apr 2, 2024 at 2:01 AM Richard Henderson
<richard.henderson@linaro.org> wrote:

> The boot process must cooperate somehow.
>
> When using loader, you must link the image such that it loads at the pc reset address
> defined by the architecture manual.
>
>
> r~

I changed my loading options to the following now to have better control:

./qemu-system-msp430 -machine msp430-launchpad -device
loader,file=simple_test.bin,addr=0xFFFE,cpu-num=0,force
-raw=on -d in_asm,out_asm

Here simple_test.bin is the raw binary file converted using objcopy.
addr=0xFFFE is the vector location where the PC will load with the
starting address.

Now how do I load the address in that reset vector location and set my
PC? Is there some example code that I can look at?

-Gautam.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Point where target instructions are read
  2024-04-03 18:15   ` Gautam Bhat
@ 2024-04-03 22:35     ` BALATON Zoltan
  2024-04-03 22:40     ` Richard Henderson
  1 sibling, 0 replies; 10+ messages in thread
From: BALATON Zoltan @ 2024-04-03 22:35 UTC (permalink / raw)
  To: Gautam Bhat; +Cc: Richard Henderson, QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 1324 bytes --]

On Wed, 3 Apr 2024, Gautam Bhat wrote:
> On Tue, Apr 2, 2024 at 2:01 AM Richard Henderson
> <richard.henderson@linaro.org> wrote:
>
>> The boot process must cooperate somehow.
>>
>> When using loader, you must link the image such that it loads at the pc reset address
>> defined by the architecture manual.
>>
>>
>> r~
>
> I changed my loading options to the following now to have better control:
>
> ./qemu-system-msp430 -machine msp430-launchpad -device
> loader,file=simple_test.bin,addr=0xFFFE,cpu-num=0,force
> -raw=on -d in_asm,out_asm

Check the docs on the generic loader: 
https://www.qemu.org/docs/master/system/generic-loader.html
I think when using cpu-num it will also set the PC but I don't know much 
about it. Maybe you could start qemu with -S option then do info registers 
in QEMU monitor to check the status to find out what's happening. If real 
board has firmware maybe you need to use that or emulate it in the board 
code if the boot loader exepects it to be present.

Regards,
BALATON Zoltan

> Here simple_test.bin is the raw binary file converted using objcopy.
> addr=0xFFFE is the vector location where the PC will load with the
> starting address.
>
> Now how do I load the address in that reset vector location and set my
> PC? Is there some example code that I can look at?
>
> -Gautam.
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Point where target instructions are read
  2024-04-03 18:15   ` Gautam Bhat
  2024-04-03 22:35     ` BALATON Zoltan
@ 2024-04-03 22:40     ` Richard Henderson
  2024-04-04  8:53       ` Peter Maydell
  1 sibling, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2024-04-03 22:40 UTC (permalink / raw)
  To: Gautam Bhat; +Cc: QEMU Developers, Peter Maydell

On 4/3/24 08:15, Gautam Bhat wrote:
> On Tue, Apr 2, 2024 at 2:01 AM Richard Henderson
> <richard.henderson@linaro.org> wrote:
> 
>> The boot process must cooperate somehow.
>>
>> When using loader, you must link the image such that it loads at the pc reset address
>> defined by the architecture manual.
>>
>>
>> r~
> 
> I changed my loading options to the following now to have better control:
> 
> ./qemu-system-msp430 -machine msp430-launchpad -device
> loader,file=simple_test.bin,addr=0xFFFE,cpu-num=0,force
> -raw=on -d in_asm,out_asm
> 
> Here simple_test.bin is the raw binary file converted using objcopy.
> addr=0xFFFE is the vector location where the PC will load with the
> starting address.
> 
> Now how do I load the address in that reset vector location and set my
> PC? Is there some example code that I can look at?

Hmm.  I can't find an example.  I see a TODO for m68k which *should* be loading the pc 
from the reset vector on reset.

What I think should work is something like

void msp430_cpu_reset_hold(Object *obj)
{
     standard stuff, mostly zeroing registers.
}

void msp430_cpu_reset_exit(Object *obj)
{
     MSP430CPUClass *mcc = MSP430_CPU_GET_CLASS(obj);
     CPUState *cs = CPU(obj);
     CPUMSP430State *env = cpu_env(cs);
     MemTxResult res;

     if (mcc->parent_phases.exit) {
         mvv->parent_phases.exit(obj);
     }

     /* Load PC from the Hard Reset interrupt vector. */
     env->pc = address_space_lduw(cs->as, 0xfffe, MEMTXATTRS_UNSPECIFIED, &res);
     assert(res == MEMTX_OK);
}

void msp430_cpu_class_init(ObjectClass *c, void *data)
{
     MSP430CPUClass *mcc = MSP430_CPU_CLASS(c);
     ResettableClass *rc = RESETTABLE_CLASS(c);

     resettable_class_set_parent_phases(rc, NULL,
                                        msp430_cpu_reset_hold,
                                        msp430_cpu_reset_exit,
                                        &mcc->parent_phases);
}

The loader device populates ram during the reset hold phase, so I believe you need to wait 
until after that is complete to perform the load, thus the reset_exit hook.


r~


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Point where target instructions are read
  2024-04-03 22:40     ` Richard Henderson
@ 2024-04-04  8:53       ` Peter Maydell
  2024-04-08 19:25         ` Gautam Bhat
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2024-04-04  8:53 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Gautam Bhat, QEMU Developers

On Wed, 3 Apr 2024 at 23:40, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 4/3/24 08:15, Gautam Bhat wrote:
> > Here simple_test.bin is the raw binary file converted using objcopy.
> > addr=0xFFFE is the vector location where the PC will load with the
> > starting address.
> >
> > Now how do I load the address in that reset vector location and set my
> > PC? Is there some example code that I can look at?
>
> Hmm.  I can't find an example.  I see a TODO for m68k which *should* be loading the pc
> from the reset vector on reset.

Arm M profile does this.

> The loader device populates ram during the reset hold phase, so I believe you need to wait
> until after that is complete to perform the load, thus the reset_exit hook.

This will not work (yet) -- CPUs do not get reset as part of the
whole-system three-phase-reset, so using the exit phase method
is not sufficient to avoid the reset ordering problem here.

You need to use rom_ptr_for_as() to see if there's a ROM blob
at the address you're trying to load the PC from, and if there
is you use ldl_p() to get the PC from the blob; otherwise you
use ldl_phys(). Searching for "initial_pc" in target/arm/cpu.c
will find you the code that does this for M-profile.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Point where target instructions are read
  2024-04-04  8:53       ` Peter Maydell
@ 2024-04-08 19:25         ` Gautam Bhat
  2024-04-09  8:53           ` Peter Maydell
  0 siblings, 1 reply; 10+ messages in thread
From: Gautam Bhat @ 2024-04-08 19:25 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Richard Henderson, QEMU Developers

On Thu, Apr 4, 2024 at 2:23 PM Peter Maydell <peter.maydell@linaro.org> wrote:

> This will not work (yet) -- CPUs do not get reset as part of the
> whole-system three-phase-reset, so using the exit phase method
> is not sufficient to avoid the reset ordering problem here.
>
> You need to use rom_ptr_for_as() to see if there's a ROM blob
> at the address you're trying to load the PC from, and if there
> is you use ldl_p() to get the PC from the blob; otherwise you
> use ldl_phys(). Searching for "initial_pc" in target/arm/cpu.c
> will find you the code that does this for M-profile.

Thanks for the tip. I am able to see the program being loaded based on
the dump of rom pointer in gdb.
Now the problem is I am loading a binary file (msp430-elf-objcopy -O
binary simple_test simple_test.bin)
and due to this I will be missing out the loader loading different
sections in the right parts of the memory.
The reset vector which is supposed to be present at 0xFFFE is present
at 0x3FFE in the binary file. How can
I fix this? Should I revert back to elf file loading?

-Gautam.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Point where target instructions are read
  2024-04-08 19:25         ` Gautam Bhat
@ 2024-04-09  8:53           ` Peter Maydell
  2024-04-10 21:15             ` Gautam Bhat
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2024-04-09  8:53 UTC (permalink / raw)
  To: Gautam Bhat; +Cc: Richard Henderson, QEMU Developers

On Mon, 8 Apr 2024 at 20:25, Gautam Bhat <mindentropy@gmail.com> wrote:
>
> On Thu, Apr 4, 2024 at 2:23 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> > This will not work (yet) -- CPUs do not get reset as part of the
> > whole-system three-phase-reset, so using the exit phase method
> > is not sufficient to avoid the reset ordering problem here.
> >
> > You need to use rom_ptr_for_as() to see if there's a ROM blob
> > at the address you're trying to load the PC from, and if there
> > is you use ldl_p() to get the PC from the blob; otherwise you
> > use ldl_phys(). Searching for "initial_pc" in target/arm/cpu.c
> > will find you the code that does this for M-profile.
>
> Thanks for the tip. I am able to see the program being loaded based on
> the dump of rom pointer in gdb.
> Now the problem is I am loading a binary file (msp430-elf-objcopy -O
> binary simple_test simple_test.bin)
> and due to this I will be missing out the loader loading different
> sections in the right parts of the memory.
> The reset vector which is supposed to be present at 0xFFFE is present
> at 0x3FFE in the binary file.

That sounds like a problem with your binary. If the reset vector
needs to be at 0xFFFE then it needs to be there, and you
should arrange for it to be built correctly. It doesn't matter
whether it's an ELF file or a raw binary file, the data has
to be in the right place. (Generally when objcopy creates a raw
binary from an ELF file it doesn't change the address where
the data is, assuming you load the resulting raw binary to the
right starting address.)

-- PMM


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Point where target instructions are read
  2024-04-09  8:53           ` Peter Maydell
@ 2024-04-10 21:15             ` Gautam Bhat
  2024-04-13 20:51               ` Gautam Bhat
  0 siblings, 1 reply; 10+ messages in thread
From: Gautam Bhat @ 2024-04-10 21:15 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Richard Henderson, QEMU Developers

On Tue, Apr 9, 2024 at 2:23 PM Peter Maydell <peter.maydell@linaro.org> wrote:

> That sounds like a problem with your binary. If the reset vector
> needs to be at 0xFFFE then it needs to be there, and you
> should arrange for it to be built correctly. It doesn't matter
> whether it's an ELF file or a raw binary file, the data has
> to be in the right place. (Generally when objcopy creates a raw
> binary from an ELF file it doesn't change the address where
> the data is, assuming you load the resulting raw binary to the
> right starting address.)
>
> -- PMM

It was a problem with me loading it to the right address. Went through
the manual again and I found that the ROM address starts at 0xC000.
Hence I was supposed to load at that address. Loading at that address
places the reset vector interrupt in the right location. Now I get the
right program counter value which is 0xC000 which is the code in the
ROM.

I went ahead to check if I now get the right opcode but I am still
getting zeroes. Digging through the code when I do the following for
translate:

static void translate(DisasContext *ctx)
{
    uint32_t opcode;

    opcode = cpu_lduw_code(ctx->msp430_cpu_state,
                    ctx->base.pc_next);
    qemu_fprintf(stderr, "Opcode: 0x%x\n", opcode);
}


cpu_lduw_code calls mmu_index callback. In my callback I have

static int msp430_cpu_mmu_index(CPUState *cp, bool ifetch)
{
    return MMU_CODE_DATA_IDX;
}

Here I have just set the MMU_CODE_DATA_IDX to 1 which I know does not
make sense. I am not sure how this index is supposed to be computed.
Any idea on what to look at to understand it?

-Gautam.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Point where target instructions are read
  2024-04-10 21:15             ` Gautam Bhat
@ 2024-04-13 20:51               ` Gautam Bhat
  0 siblings, 0 replies; 10+ messages in thread
From: Gautam Bhat @ 2024-04-13 20:51 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Richard Henderson, QEMU Developers

Ah I had my .tlb_fill callback set to an empty function with just
returning true. I need to put the actual code there. Let me fill this
function up and see what happens.

-Gautam.

On Thu, Apr 11, 2024 at 2:45 AM Gautam Bhat <mindentropy@gmail.com> wrote:
>
> On Tue, Apr 9, 2024 at 2:23 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> > That sounds like a problem with your binary. If the reset vector
> > needs to be at 0xFFFE then it needs to be there, and you
> > should arrange for it to be built correctly. It doesn't matter
> > whether it's an ELF file or a raw binary file, the data has
> > to be in the right place. (Generally when objcopy creates a raw
> > binary from an ELF file it doesn't change the address where
> > the data is, assuming you load the resulting raw binary to the
> > right starting address.)
> >
> > -- PMM
>
> It was a problem with me loading it to the right address. Went through
> the manual again and I found that the ROM address starts at 0xC000.
> Hence I was supposed to load at that address. Loading at that address
> places the reset vector interrupt in the right location. Now I get the
> right program counter value which is 0xC000 which is the code in the
> ROM.
>
> I went ahead to check if I now get the right opcode but I am still
> getting zeroes. Digging through the code when I do the following for
> translate:
>
> static void translate(DisasContext *ctx)
> {
>     uint32_t opcode;
>
>     opcode = cpu_lduw_code(ctx->msp430_cpu_state,
>                     ctx->base.pc_next);
>     qemu_fprintf(stderr, "Opcode: 0x%x\n", opcode);
> }
>
>
> cpu_lduw_code calls mmu_index callback. In my callback I have
>
> static int msp430_cpu_mmu_index(CPUState *cp, bool ifetch)
> {
>     return MMU_CODE_DATA_IDX;
> }
>
> Here I have just set the MMU_CODE_DATA_IDX to 1 which I know does not
> make sense. I am not sure how this index is supposed to be computed.
> Any idea on what to look at to understand it?
>
> -Gautam.


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2024-04-13 20:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-01 19:50 Point where target instructions are read Gautam Bhat
2024-04-01 20:31 ` Richard Henderson
2024-04-03 18:15   ` Gautam Bhat
2024-04-03 22:35     ` BALATON Zoltan
2024-04-03 22:40     ` Richard Henderson
2024-04-04  8:53       ` Peter Maydell
2024-04-08 19:25         ` Gautam Bhat
2024-04-09  8:53           ` Peter Maydell
2024-04-10 21:15             ` Gautam Bhat
2024-04-13 20:51               ` Gautam Bhat

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.