Gautam Bhat <mindentr...@gmail.com> writes:

> On Mon, May 15, 2023 at 7:22 PM Alex Bennée <alex.ben...@linaro.org> wrote:
>>
>>
>> Gautam Bhat <mindentr...@gmail.com> writes:
>>
>> > Hi,
>> >
>> > I am going through some translation code for existing targets.
>> >
>> > I would like to know if there are any good resources on deeper
>> > understanding of translation blocks? Also some advice on the best way
>> > to read code related to translation in Qemu and trying it out maybe
>> > using the debugger, printing etc? I am getting lost trying to make
>> > sense of the translation code.
>>
>> We have a section in the developers manual that gives an overview of the
>> translator and how it goes together:
>>
>>   https://qemu.readthedocs.io/en/latest/devel/index-tcg.html
>>
<snip>
>
> Thanks for the resources. I have been going through the documentation
> and also running it using a debugger to analyze the code. I am still
> not there with the op code emulation.
> I am more or less stuck understanding how to handle translator_ops
> callbacks and disassembly
>
> I will be specific.
>
> 1. Could you please explain what the state machine should be for the
> tb_stop(...) callback? I am looking at code from AVR
> and Microblaze architecture and I see the following cases:
> DISAS_NORETURN, DISAS_NEXT, DISAS_TOO_MANY, DISAS_LOOKUP and
> DISAS_EXIT.  Is there some documentation on how to handle these cases
> and how the disassembly goes through these states?

The core documentation is in translator.h

  /**
   * DisasJumpType:
   * @DISAS_NEXT: Next instruction in program order.
   * @DISAS_TOO_MANY: Too many instructions translated.
   * @DISAS_NORETURN: Following code is dead.
   * @DISAS_TARGET_*: Start of target-specific conditions.
   *
   * What instruction to disassemble next.
   */

but as you can see the various frontends define there own target
specific end cases. Currently you have to look at target specific code
to see what it is handling.

Broadly there are two types of exit:

  - goto_tb + exit_tb

  We create an exit block with two exit cases, typically the two legs of
  a conditional branch. Initially these slots are empty which forces an
  exit to the main loop. Then the translated block matching the next PC
  is looked up and patched into the source TB so next time we jump
  directly.

  - lookup_and_goto_ptr

  We don't know what PC we might reach at the end of the block so we
  need to dynamically find the next TB based on what the PC is at
  execution time. If we can't find a TB we trigger an exit to the main
  loop so one can be translated.

The other cases are various special cases. For example we might not be
executing a branch and just falling through to the next instruction
(DISAS_NEXT). We might know the helper will never return, for example
because and exception is triggered, in which case we return to the main
loop and process it there.
 

> 2. How should the callback for translate_insn be handled?

It is called for each instruction in a block.

> 3. Do you have more information or a visual diagram of sorts for
> TARGET_PAGE_* and PAGE_* and the relation between translation blocks
> and pages? Also how
> should one handle where architectures don't have any paging?

All system emulation is handled by page size because that is the
fundamental granularity of the softmmu TLB which looks up a translation
from guest address to offset into the memory region. It is not directly
related to if the guest is using paging to implement virtual memory.

>
> Thanks,
> Gautam.


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro

Reply via email to