[Libre-soc-bugs] [Bug 982] Support PowerPC ABI in ISACaller

bugzilla-daemon at libre-soc.org bugzilla-daemon at libre-soc.org
Mon Sep 18 22:34:43 BST 2023


https://bugs.libre-soc.org/show_bug.cgi?id=982

--- Comment #61 from Dmitry Selyutin <ghostmansd at gmail.com> ---
(In reply to Andrey Miroshnikov from comment #59)
> Before I forget, at least three syscalls (only 'exit' is really in scope of
> this task) need to be bypassed as they will affect the host python program:
> exit, pause, vfork:
> https://github.com/ssavvides/execute-syscall/blob/master/execute_syscall.
> py#L210

Almost everything is to be bypassed; other syscalls also make little sense
unless they are bypassed. Some can be bypassed in a simpler way, e.g. those
which don't have side-effects, like gettid, getpid, gettime, et al.; some need
cooperation wrt resources (memory and descriptors) but are doable; some are
difficult and I'm not even sure what their semantics would be (e.g. what does
it mean to execve, fork or signal inside the emulator?).
The three to be bypassed are shown as those which make little sense in the
context of the emulation; there is a rationale above the skip list. I wouldn't
say exit makes no sense though, that's kinda like simulation stop in our realm.
But you should discuss it with Luke.


(In reply to Andrey Miroshnikov from comment #60)
> (In reply to Dmitry Selyutin from comment #58)
> > I suggest that at this point I reserve the rest of the works to Andrey. I
> > think that, with a couple of minor modifications (e.g. extending it with
> > memmap and fdtree arguments), this should be fine to wrap syscalls. Please
> > try not to make it too invasive; the code should not itself depend on
> > ISACaller, just on the interfaces.
> 
> Are you saying I should be able to do this without modifying ISACaller
> source at all?
> I guess if there's a way to pause ISACaller execution, inspect mem/reg's,
> then actually I don't need to touch ISACaller at all!

Well, some bits are still to be touched. You have to establish the interrupt
descriptor table. Basically, when you execute the system call, the processor
triggers an interrupt; it happens that the processor is programmed or
instructed by OS to jump at some special code section and continue execution
there (with the return address and arguments saved, typically on stack or via
registers). You can instruct the simulator to behave respectively when it sees
this handler, i.e. when sumulator realizes it's on the same instruction counter
as where the handler begins.
When you found the fact that you're executing the exact place as where the
handler belongs, the Python code in simulator can simply be instructed to read
self.gpr(XXX) based on the calling convention (just check ISA reference, they
should mention "sc" parameters passing). Linux system calls generally don't use
stack and never use FPRs, so you don't have to care about stack. Something like
this (pseudocode, you have to dig it in ISACaller, I'm a rare guest there; I'm
assuming registers 3..10, but you have to check):

$ cat sim.py
def __init__(self, initial_mem, regs):
    self.program_msrs_and_interrupts() # should likely be done by PPC assembly
upon simulator start

def event_loop(self, ...):
    while True:
        syscall = syscalls.Dispatcher(guest="ppc",
host=YOUR_HOST_AS_PER_PYTHON)
        pc = self.get_next_insn()
        if pc == MAGIC_HANDLER:
            sysnum = self.gpr(3)
            sysargs = [self.gpr(4), self.gpr(5), self.gpr(6), self.gpr(7),
self.gpr(8), self.gpr(9), self.gpr(10)]
            rv = syscall(sysnum, *sysargs)
            self.gpr(3) = rv # beware, might be a multi-word; likely you need
to set both


I'm not aware of PPC architecture enough; I could give you a vague hints on x86
only. I can try and check PPC ISA in this regard, if you want, but it'd be
simpler to ask Jacob or Luke or perhaps Konstantinos (I'm not sure whether he
dealt with PPC syscalls though). But I see that you alredy do something
suspiciously similar in src/openpower/test/syscall/syscall_cases.py. :-)

Practically speaking, it's just the same function call, except that you do not
jump directly. You interrupt the processor, it switches the context and
priviledge level, then jumps to a specific pre-programmed location, then the
kernel code serves the request. There's an awful lot of details inbetween these
stages, but basically (dramatically simplified) this is it.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the libre-soc-bugs mailing list