From c2eb7188860145fe12de631514de1eb306d99c56 Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Wed, 2 Jul 2014 16:18:50 +0200 Subject: [PATCH] sal/bochs: catch all I/O instructions Up to now, the IOPortListener only caught invocations of INB/OUTB with the port number in DX and 8-bit input/output (from/to AL), but none of the various other methods to access the I/O port range (e.g., by 8-bit immediate port numbers). This change is supposed to catch all other cases, too. Change-Id: I1180cd9c1d59df600067739817adab684b18a608 --- src/core/sal/bochs/IOPortCom.ah | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/core/sal/bochs/IOPortCom.ah b/src/core/sal/bochs/IOPortCom.ah index a0bb35fc..26a0ab0a 100644 --- a/src/core/sal/bochs/IOPortCom.ah +++ b/src/core/sal/bochs/IOPortCom.ah @@ -12,29 +12,33 @@ #include "../SALInst.hpp" #include "BochsHelpers.hpp" -// TODO: ATM only capturing bytewise output (most common, I suppose) +// FIXME ATM only capturing the first byte of a multi-byte in/out aspect IOPortCom { - pointcut outInstruction() = "% ...::bx_cpu_c::OUT_DXAL(...)"; + pointcut devices_outp() = "% ...::bx_devices_c::outp(...)"; - advice execution (outInstruction()) : after () + advice call (devices_outp()) && within ("...::bx_cpu_c") : before () { - unsigned rDX = getCPU(tjp->that())->gen_reg[2].word.rx; // port number - unsigned char rAL = getCPU(tjp->that())->gen_reg[0].word.byte.rl; // data - - // Detect the CPU that triggered the change: + unsigned port = *(tjp->arg<0>()); + unsigned data = *(tjp->arg<1>()); + + // detect the CPU that triggered the access fail::ConcreteCPU& triggerCPU = fail::simulator.detectCPU(getCPU(tjp->that())); - fail::simulator.onIOPort(&triggerCPU, rAL, rDX, true); + // forward to SimulatorController + fail::simulator.onIOPort(&triggerCPU, data, port, true); } - pointcut inInstruction() = "% ...::bx_cpu_c::IN_ALDX(...)"; + pointcut devices_inp() = "% ...::bx_devices_c::inp(...)"; - advice execution (inInstruction()) : after () + advice call (devices_inp()) && within ("...::bx_cpu_c") : after () { - unsigned rDX = getCPU(tjp->that())->gen_reg[2].word.rx; // port number - unsigned char rAL = getCPU(tjp->that())->gen_reg[0].word.byte.rl; // data + unsigned port = *(tjp->arg<0>()); + unsigned data = *(tjp->result()); + + // detect the CPU that triggered the access fail::ConcreteCPU& triggerCPU = fail::simulator.detectCPU(getCPU(tjp->that())); - fail::simulator.onIOPort(&triggerCPU, rAL, rDX, false); + // forward to SimulatorController + fail::simulator.onIOPort(&triggerCPU, data, port, false); } };