Hi folks. I'm looking for a way to enable the m5 utility/pseudo
instructions with fast model CPUs, and it's a little more complicated than
I'd initially assumed.

I knew there was a memory mapped mechanism to support the pseudo
instructions, and that that was added to enable those instructions in KVM
mode. That is done using the finalizePhysical method on the TLBs which
detects accesses within certain ranges, and then redirects them to memory
mapped IPRs (an Alpha-ism) which handle the pseudo instruction.

The problem with this approach and fast models is that, for starters, the
port to memory comes out of the fast model already collected from all the
cores that make up a cluster. It isn't possible as far as I can tell to
determine which core (and hence which context) a given request came from to
plumb up the "IPR" access correctly.

Then beyond that, the accesses come out an AMBA flavor of TLM (the systemc
communication mechanism), and those have to be translate first to regular
TLM, and then to gem5's protocol using separate bridge objects. There isn't
anywhere to insert a call to the finalizePhysical call or equivalent to
intercept requests to the psuedo instruction device.

One possible solution would be to use a mechanism called semihosting which
is supported by the fast models. Basically, using the SVC instruction with
a magic number (SVC is usually used for system calls) will trap into the
simulation mechanism. The value in R0 is supposed to say what service you
want (read from a file, write to stdout, etc), and then additional
parameters are in a blob pointed to by r1. The IRIS API, a debug API we're
using to implement ThreadContexts for the fast models, has an interface to
trap semihosting events, so it should be possible to run semihosting
instructions, capture them with the IRIS interface, and use that (which
knows what ThreadContext is relevant) to implement a call into the pseudo
instructions.

This *should* work for fast model CPUs, and it shouldn't be difficult to
add into the native gem5 CPUs where we control what all the instructions
do. KVM, on the other hand, is a bit trickier. I've been digging around in
the KVM and QEMU source, and while QEMU says it supports semihosting, I
don't see anything that makes it look like it supports semihosting *and*
KVM at the same time. That may work through some magic I'm not seeing, but
if I can't find it I can't reimplement it in gem5 :-).

It looks like KVM used to support a hypercall exit, but I see a change from
the Xen hypervisor guys that made KVM eat all hypercalls internally and not
forward any of them to userspace. They say to use KVM_EXIT_IO on x86 and
KVM_EXIT_MMIO on non-x86 systems to get the same effect. In either case, I
think that forces us into what we have now, where the m5 binary uses
magical addresses to do its work. I think we could switch to using an IO
port on x86 though, and a small window on ARM. In all cases we have access
to the relevant thread context so we don't need to worry about having a big
window for passing around parameters.


All this also brings up an idea I had a while ago where I wanted to unify
and generalize the pseudo instruction and system call catching code. In
both cases, gem5 is intercepting a particular instruction and then doing
something special, and it would be nice to have those work in the same way,
and to be able to add new types of calls into gem5 to, for instance,
emulate BIOS interrupts. The idea would be to have a system call call into
an actual stub, but then the stub would use the pseudo instruction
mechanism to call into gem5. gem5 would then know to do a system call or
whatever. This would remove one more difference between SE and FS mode
which would also be nice.
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to