0

I want to extend the QEMU TCG (tiny code generator) to accept new instructions for the risc-v guest on my x86 machine. However, I have no experience on how the TCG works, so I was wondering if someone can give me some useful pointers on where to start understanding how the TCG works in the QEMU source code? I know there is a frontend and backend, but I don't really understand where the translation actually happens, and how are the instruction translated.

I also saw the insn32.decode file in target/riscv defining the opcodes for various operators like lui, but I am not sure how that file is used and if it's for the TCG target (ie a risc-v host) or the QEMU guest.

I am looking for something like QEMU - Code Flow [ Instruction cache and TCG] but up-to-date with current QEMU version.

Any help is appreciated.

John
  • 121
  • 3
  • 14
  • 1
    The diagram in the answer you link to is still broadly correct, although some files have moved around a little (eg target-XXX/ is now target/XXX/) and some function names may have changed. – Peter Maydell Sep 04 '20 at 15:17
  • Thank you for the answer. Also https://stackoverflow.com/questions/15485257/qemu-source-code-flow?noredirect=1&lq=1 helped me. – John Sep 05 '20 at 09:45
  • What I don't understand is how the backend works, ie how the the tcg_gen_* function and respective tcg_gen_op* in the frontend arrive to the backend and where are they processed (in my case the host is an x86) – John Sep 05 '20 at 09:48
  • 1
    If you're working on the guest frontend then you generally don't need to care about details of how the backend works -- it's all well-tested working code, so you can just emit the TCG intermediate-representation ops you need, and you can debug at the level of the IR using the -d option flags. I rarely even look at the generated host code. – Peter Maydell Sep 05 '20 at 21:20
  • What I am trying to emulate is an instruction that performs in-memory operations, depending on the address of the load. I think this is the best way to do it, due to the more abstract memory view of QEMU. For example, it should perform a copy from one memory address to another, with a very big size (>= 16Kb, the DRAM row size). However, I don't think I can put this kind of logic into the frontend (check the size, check the actual address passed in rs1, perform many loads/stores). That's why I probably need the backend too. What do you think? – John Sep 06 '20 at 06:54
  • I also would need to perform virtual to physical address, for example. Something like `src = memory_region_get_ram_ptr(); dst = memory_region_get_ram_ptr(); memcpy(dst,src, size)` in the backend would be ideal, and that's what I would like to figure out if it's feasible – John Sep 06 '20 at 09:18
  • 1
    You'd want to do that kind of thing in a helper function rather than directly in generated code, but it's all still front-end stuff. The Arm dc zva does a block-memory-clear which has a fast-path "find the underlying host ram ptr and use it if possible", for instance, and the s390 target has something similar. – Peter Maydell Sep 06 '20 at 10:02
  • Thank you for the help, Peter. Helper did the trick. I found both the Arm dc zva patch you sent in 2014 and the s390x memset. One last thing: both code use `helper_ret_stb_mmu`, but I don't understand what this function does on TLB. Also, is there any difference between running this as user mode or system? – John Sep 10 '20 at 09:43
  • And copy data from one section of memory to the other won't have side effects on caches, since there aren't in QEMU, correct? – John Sep 10 '20 at 09:45

0 Answers0