From cdd445a72085ee3faa35826a2c0449907a0504f7 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 30 Nov 2023 23:15:45 -0800 Subject: [PATCH] ISACaller: fix syscall emulation there were two bugs fixed: 1. sc emulation was missing a `return`, so it tried to run sc again after running sc and rfid, giving the wrong CIA and MSR values. 2. the code to replace and restore the instruction with rfid had the wrong endian on the load, so it was corrupting the instruction for the next time it was used. I just deleted the save/replace/restore code since it isn't needed anymore. I then changed the syscall tests to ensure both the bugs above don't happen again. --- src/openpower/decoder/isa/caller.py | 6 +----- src/openpower/decoder/isa/test_syscall.py | 11 +++++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 735252c7..409fedfb 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -2011,8 +2011,6 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop): # 2. Call the HDL implementation which invokes trap. # 3. Reroute the guest system call to host system call. # 4. Force return from the interrupt as if we had guest OS. - # "executing" rfid requires putting 0x4c000024 temporarily - # into the program at the PC. TODO investigate and remove if ((asmop in ("sc", "scv")) and (self.syscall is not None) and not syscall_emu_active): @@ -2030,10 +2028,8 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop): self.gpr.write(3, result, False, self.namespace["XLEN"]) # Return from interrupt - backup = self.imem.ld(pc, 4, False, True, instr_fetch=True) - self.imem.st(pc, 0x4c000024, width=4, swap=True) yield from self.call("rfid", syscall_emu_active=True) - self.imem.st(pc, backup, width=4, swap=True) + return elif ((name in ("rfid", "hrfid")) and syscall_emu_active): asmop = "rfid" diff --git a/src/openpower/decoder/isa/test_syscall.py b/src/openpower/decoder/isa/test_syscall.py index 2bbd27da..580bdbcd 100644 --- a/src/openpower/decoder/isa/test_syscall.py +++ b/src/openpower/decoder/isa/test_syscall.py @@ -62,14 +62,15 @@ class SyscallTestCase(FHDLTestCase): MSR[52:58] = SRR1[52:58] MSR[60:64] = SRR1[60:64] - self.assertEqual(sim.spr['SRR0'], 8) # PC to return to: CIA+4 + self.assertEqual(sim.spr['SRR0'], 4) # PC to return to: CIA+4 self.assertEqual(sim.spr['SRR1'], SRR1) # MSR to restore after sc return - # FIXME this is currently hardcoded to the same way as in test_trap.py. - # However, I'd have expected 0x9000000000002903, not 0x9000000000000001. - MSR = SelectableInt(0x9000000000000001, 64) + MSR = SelectableInt(0x9000000000002903, 64) self.assertEqual(sim.msr, MSR) # MSR changed to this by sc/trap + # we need to actually return to right after the sc + self.assertEqual(sim.pc.CIA, 4) + print("SYSCALL SRR1", hex(int(SRR1)), hex(int(sim.spr['SRR1']))) print("SYSCALL MSR", hex(int(MSR)), hex(int(sim.msr)), hex(DEFAULT_MSR)) return sim @@ -80,6 +81,8 @@ class SyscallTestCase(FHDLTestCase): initial_regs[0] = 20 # getpid with Program(lst, bigendian=False) as program: sim = self.run_tst_program(program, initial_regs) + self.assertEqual(hex(sim.imem.ld(0, width=8, swap=False)), + "0x44000002", "insn wasn't restored correctly") self.assertEqual(sim.gpr(3), os.getpid()) def test_sc_getuid(self): -- 2.30.2