Re: How to run different firmware in a machine with 2 cpu?

2023-04-12 Thread Huang Canming
I seem to find the cause.

when qemu read init-sp and init-pc from rom:

rom = rom_ptr_for_as(s->as, vecbase, 8);   (target/arm/cpu.c)

the func rom_ptr_for_as did not check for the Addressspace,  as the comment
says

>  * Note that we do not check @as against the 'as' member in the
>  * 'struct Rom' returned by rom_ptr(). The Rom::as is the
>  * AddressSpace which the rom blob should be written to, whereas
>  * our @as argument is the AddressSpace which we are (effectively)
>  * reading from, and the same underlying RAM will often be visible
>  * in multiple AddressSpaces. (A common example is a ROM blob
>  * written to the 'system' address space but then read back via a
>  * CPU's cpu->as pointer.) This does mean we might potentially
>  * return a false-positive match if a ROM blob was loaded into an
>  * AS which is entirely separate and distinct from the one we're
>  * querying, but this issue exists also for rom_ptr() and hasn't
>  * caused any problems in practice.
>

So in this case above, the second cpu would load the rom of the first cpu,
and set the wrong stackpointer when reset.

For now, I add a func called rom_ptr_with_as, to find a rom and check its
AddressSpace,
and now the 2 cpu could work normally. And I don't know this is a QEMU
issue or not.
Seems that there were not such problems before?

--Canming Huang


Huang Canming  于2023年4月10日周一 15:11写道:

> Thank you very much for this explanation! For now, I use the generic
> loader and it could almost work now.
>
> ./qemu-system-arm -M mymachine -smp 2 \
> -device loader,file=./scp_fast_model.elf,addr=0x0,cpu-num=0 \
>  -device loader,file=./mcp_fast_model.elf,addr=0x0,cpu-num=1  \
> -serial stdio -serial tcp::5678,server=on,wait=off
>
> the 2 cpu(or SOC), one is called "*mcp*",  the other is "*scp*"
>
> while there are still problems:
> *The ram size of "mcp" is 0x2, and the ram size of "scp" is 0x4
> (In real machine)*.
> If I use the cmd above, QEMU will still abort:
> qemu-system-arm: ../target/arm/cpu.h:2396: arm_is_secure_below_el3:
> Assertion failed.
>
> When I used gdb to debug, I found that the "mcp" seem to be trying  to
> access *0x3FFF0*  of ram, which is out of its range.
> While the program of mcp is correct because I have run it in singly
> before( comment all the "scp" related code).
>
> And If I edit the ram size of "mcp" to 0x4, then the programs of mcp
> and scp could all run well.
>
> the code to create rom and ram:
> create_ram(_mem,0x00,"scp.rom",0x4);
> create_ram(_mem,0x2000,"scp.ram",0x4);
>
> create_ram(_mem,0x00,"mcp.rom",0x2);
> create_ram(_mem,0x2000,"mcp.ram",0x4);
>
> static MemoryRegion *create_ram(MemoryRegion *mr,hwaddr addr, const char *
> name,uint64_t size){
> MemoryRegion *mem = g_new(MemoryRegion, 1);
> memory_region_init_ram(mem, NULL, name,size,
> _fatal);
> memory_region_add_subregion(mr, addr, mem);
> return mem;
> }
>
> I have no idea what is wrong. Do you have any ideas?
>
>
>
>


Re: How to run different firmware in a machine with 2 cpu?

2023-04-10 Thread Huang Canming
Thank you very much for this explanation! For now, I use the generic loader
and it could almost work now.

./qemu-system-arm -M mymachine -smp 2 \
-device loader,file=./scp_fast_model.elf,addr=0x0,cpu-num=0 \
 -device loader,file=./mcp_fast_model.elf,addr=0x0,cpu-num=1  \
-serial stdio -serial tcp::5678,server=on,wait=off

the 2 cpu(or SOC), one is called "*mcp*",  the other is "*scp*"

while there are still problems:
*The ram size of "mcp" is 0x2, and the ram size of "scp" is 0x4 (In
real machine)*.
If I use the cmd above, QEMU will still abort:
qemu-system-arm: ../target/arm/cpu.h:2396: arm_is_secure_below_el3:
Assertion failed.

When I used gdb to debug, I found that the "mcp" seem to be trying  to
access *0x3FFF0*  of ram, which is out of its range.
While the program of mcp is correct because I have run it in singly before(
comment all the "scp" related code).

And If I edit the ram size of "mcp" to 0x4, then the programs of mcp
and scp could all run well.

the code to create rom and ram:
create_ram(_mem,0x00,"scp.rom",0x4);
create_ram(_mem,0x2000,"scp.ram",0x4);

create_ram(_mem,0x00,"mcp.rom",0x2);
create_ram(_mem,0x2000,"mcp.ram",0x4);

static MemoryRegion *create_ram(MemoryRegion *mr,hwaddr addr, const char *
name,uint64_t size){
MemoryRegion *mem = g_new(MemoryRegion, 1);
memory_region_init_ram(mem, NULL, name,size,
_fatal);
memory_region_add_subregion(mr, addr, mem);
return mem;
}

I have no idea what is wrong. Do you have any ideas?


Re: How to run different firmware in a machine with 2 cpu?

2023-04-08 Thread Peter Maydell
On Fri, 7 Apr 2023 at 17:05, Huang Canming  wrote:
>
> Sorry for the wrong cmd. It'a typo after I edit the sample command.
> my command is: ./qemu-system-arm -M mymachine -smp cpus=2 -kernel test1.elf 
> -bios test2.elf -serial stdio -serial tcp::5678,server=on,wait=off
> which use 'kernel' and "bios" to load different firmwares to the 2 cpus.
>
>> You should only call armv7m_load_kernel() once, even if there
>> is more than one CPU in the system.
>
> So I need to use  generic loader to load file into cpu and then do cpu reset 
> by myself(which was done in armv7m_load_kernel).

No, you don't need to do cpu reset yourself. Your board
code must call armv7m_load_kernel() once and only once.

> I have a few further question:
> in such cases, do I need a second sysbus? or can the 2 cpus use the same 
> sysbus?

"sysbus" is just an odd artefact of an old bit of QEMU's
design. There is no "bus" there particularly - it only matters
for ensuring that devices of type SYSBUS get reset.
There is always exactly one sysbus.

> and why the armv7m_load_kernel can only be called once?

It must be called exactly once because it does some work like
arranging for the CPUs to be reset. If you don't call it,
the CPU reset doesn't work right; if you call it twice then
it gets confused.

-- PMM



Re: How to run different firmware in a machine with 2 cpu?

2023-04-07 Thread Huang Canming
Sorry for the wrong cmd. It'a typo after I edit the sample command.
my command is: ./qemu-system-arm -M mymachine -smp cpus=2 -kernel test1.elf
-bios test2.elf -serial stdio -serial tcp::5678,server=on,wait=off
which use 'kernel' and "bios" to load different firmwares to the 2 cpus.

You should only call armv7m_load_kernel() once, even if there
> is more than one CPU in the system.

So I need to use  generic loader to load file into cpu and then do cpu
reset by myself(which was done in armv7m_load_kernel).
Thank you. I will try it.

I have a few further question:
in such cases, do I need a second sysbus? or can the 2 cpus use the same
sysbus?
and why the armv7m_load_kernel can only be called once?

Thank you for your time.

Peter Maydell  于2023年4月7日周五 23:22写道:

> On Fri, 7 Apr 2023 at 11:41, Huang Canming  wrote:
> >
> > hi, members.
> >
> > I'm trying to model a custom machine which has 2 cpus. Each cpu has its
> own ram/rom.
> >
> > for now, I have create a different MemoryRegion for the 2 cpu.
> >
> > I want that the 2 cpu could run differnt firmware, so I use
> >
> > armv7m_load_kernel(ARM_CPU(cpu1),machine->firmware,0,0x1)
> > armv7m_load_kernel(ARM_CPU(cpu2),machine->kernel_filename,0,0x1)
>
> You should only call armv7m_load_kernel() once, even if there
> is more than one CPU in the system.
>
> If you want to do something more complex than "just load
> one file", then look at the "generic loader", which will
> allow you to specifically say "load this ELF file into
> the address space as seen by this particular CPU".
> https://www.qemu.org/docs/master/system/generic-loader.html
>
> > ./qemu-system-arm -M mymachine -smp cpus=2 -kernel test1.elf -test2.elf
> -serial stdio -serial tcp::5678,server=on,wait=off
>
> This command line doesn't make sense and I'm surprised it
> didn't generate an error, because "-test2.elf" isn't a valid option.
>
> thanks
> -- PMM
>


Re: How to run different firmware in a machine with 2 cpu?

2023-04-07 Thread Peter Maydell
On Fri, 7 Apr 2023 at 11:41, Huang Canming  wrote:
>
> hi, members.
>
> I'm trying to model a custom machine which has 2 cpus. Each cpu has its own 
> ram/rom.
>
> for now, I have create a different MemoryRegion for the 2 cpu.
>
> I want that the 2 cpu could run differnt firmware, so I use
>
> armv7m_load_kernel(ARM_CPU(cpu1),machine->firmware,0,0x1)
> armv7m_load_kernel(ARM_CPU(cpu2),machine->kernel_filename,0,0x1)

You should only call armv7m_load_kernel() once, even if there
is more than one CPU in the system.

If you want to do something more complex than "just load
one file", then look at the "generic loader", which will
allow you to specifically say "load this ELF file into
the address space as seen by this particular CPU".
https://www.qemu.org/docs/master/system/generic-loader.html

> ./qemu-system-arm -M mymachine -smp cpus=2 -kernel test1.elf -test2.elf 
> -serial stdio -serial tcp::5678,server=on,wait=off

This command line doesn't make sense and I'm surprised it
didn't generate an error, because "-test2.elf" isn't a valid option.

thanks
-- PMM



Re: How to run different firmware in a machine with 2 cpu?

2023-04-07 Thread Huang Canming
sorry for lack my start cmd:
./qemu-system-arm -M mymachine -smp cpus=2 -kernel test1.elf -test2.elf
-serial stdio -serial tcp::5678,server=on,wait=off

Huang Canming  于2023年4月7日周五 18:40写道:

> hi, members.
>
> I'm trying to model a custom machine which has 2 cpus. Each cpu has its
> own ram/rom.
>
> for now, I have create a different MemoryRegion for the 2 cpu.
>
> I want that the 2 cpu could run differnt firmware, so I use
>
> armv7m_load_kernel(ARM_CPU(cpu1),machine->firmware,0,0x1)
> armv7m_load_kernel(ARM_CPU(cpu2),machine->kernel_filename,0,0x1)
>
> but it seems could not work normally:
>
> qemu-system-arm: ../target/arm/cpu.h:2396: arm_is_secure_below_el3:
> Assertion failed.
>
> so I wonder is there something need to do to achieve this but I ignore? do
> I need a second sysbus for cpu2(default sysbus for cpu1)? I create the
> other sysbus for cpu2, but it didn't solve the problem.
>
> Thank you for your time to read my email, Looking forward to hearing from
> you.
>
>
>