Re: Point where target instructions are read
On Sun, Apr 14, 2024 at 2:21 AM Gautam Bhat wrote: > > 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. Got it working. I can see the opcode now. Let me proceed with further implementation of decoding opcodes etc. Thanks for the help. -Gautam.
Re: Point where target instructions are read
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 wrote: > > On Tue, Apr 9, 2024 at 2:23 PM Peter Maydell 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.
Re: Point where target instructions are read
On Tue, Apr 9, 2024 at 2:23 PM Peter Maydell 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.
Re: Point where target instructions are read
On Mon, 8 Apr 2024 at 20:25, Gautam Bhat wrote: > > On Thu, Apr 4, 2024 at 2:23 PM Peter Maydell 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
Re: Point where target instructions are read
On Thu, Apr 4, 2024 at 2:23 PM Peter Maydell 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.
Re: Point where target instructions are read
On Wed, 3 Apr 2024 at 23:40, Richard Henderson 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
Re: Point where target instructions are read
On 4/3/24 08:15, Gautam Bhat wrote: On Tue, Apr 2, 2024 at 2:01 AM Richard Henderson 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~
Re: Point where target instructions are read
On Wed, 3 Apr 2024, Gautam Bhat wrote: On Tue, Apr 2, 2024 at 2:01 AM Richard Henderson 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.
Re: Point where target instructions are read
On Tue, Apr 2, 2024 at 2:01 AM Richard Henderson 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.
Re: Point where target instructions are read
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 0x07fa + tb prologue 0x7fff6403fe00: 8b 5d f0 movl -0x10(%rbp), %ebx 0x7fff6403fe03: 85 dbtestl%ebx, %ebx 0x7fff6403fe05: 0f 8c 1c 00 00 00jl 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 0x7fff6418 0x7fff6403fe27: 48 8d 05 15 ff ff ff leaq -0xeb(%rip), %rax 0x7fff6403fe2e: e9 e5 01 fc ff jmp 0x7fff6418 ===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~