Fixes for MONITOR/MWAIT - the feature is still EXPERIMENTAL ONLY !

This commit is contained in:
Stanislav Shwartsman 2008-10-03 16:53:08 +00:00
parent 5d0a807f0e
commit fb71c07b15
2 changed files with 19 additions and 11 deletions

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.529 2008-10-01 09:44:40 sshwarts Exp $ // $Id: cpu.h,v 1.530 2008-10-03 16:53:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -756,14 +756,14 @@ typedef struct {
struct monitor_addr_t { struct monitor_addr_t {
bx_phy_address monitor_begin; bx_phy_address monitor_begin;
bx_phy_address monitor_end; bx_phy_address monitor_end;
bool armed;
// avoid false trigger when MONITOR was not set up properly // avoid false trigger when MONITOR was not set up properly
monitor_addr_t(): monitor_addr_t():
monitor_begin(0xffffffff), monitor_end(0xffffffff) {} monitor_begin(0xffffffff), monitor_end(0xffffffff), armed(false) {}
monitor_addr_t(bx_phy_address addr, unsigned len): monitor_addr_t(bx_phy_address addr, unsigned len):
monitor_begin(addr), monitor_end(addr+len) {} monitor_begin(addr), monitor_end(addr+len), armed(true) {}
void reset_monitor(void) { monitor_begin = monitor_end = 0xffffffff; } void reset_monitor(void) { monitor_begin = monitor_end = 0xffffffff; armed = false; }
}; };
#endif #endif

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.261 2008-09-19 19:18:56 sshwarts Exp $ // $Id: proc_ctrl.cc,v 1.262 2008-10-03 16:53:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -1906,6 +1906,7 @@ void BX_CPU_C::check_monitor(bx_phy_address begin_addr, unsigned len)
BX_CPU_THIS_PTR debug_trap &= ~BX_DEBUG_TRAP_SPECIAL; BX_CPU_THIS_PTR debug_trap &= ~BX_DEBUG_TRAP_SPECIAL;
// clear monitor // clear monitor
BX_MEM(0)->clear_monitor(BX_CPU_THIS_PTR bx_cpuid); BX_MEM(0)->clear_monitor(BX_CPU_THIS_PTR bx_cpuid);
BX_CPU_THIS_PTR monitor.reset_monitor();;
} }
} }
#endif #endif
@ -1979,6 +1980,13 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MONITOR(bxInstruction_c *i)
BX_CPU_THIS_PTR monitor.monitor_begin = paddr; BX_CPU_THIS_PTR monitor.monitor_begin = paddr;
BX_CPU_THIS_PTR monitor.monitor_end = paddr + CACHE_LINE_SIZE; BX_CPU_THIS_PTR monitor.monitor_end = paddr + CACHE_LINE_SIZE;
// Set the monitor immediately. If monitor is still armed when we MWAIT,
// the processor will stall.
bx_pc_system.invlpg(BX_CPU_THIS_PTR monitor.monitor_begin);
if ((BX_CPU_THIS_PTR monitor.monitor_end & ~0xfff) != (BX_CPU_THIS_PTR monitor.monitor_begin & ~0xfff))
bx_pc_system.invlpg(BX_CPU_THIS_PTR monitor.monitor_end);
BX_DEBUG(("MONITOR for phys_addr=0x" FMT_PHY_ADDRX, BX_CPU_THIS_PTR monitor.monitor_begin));
BX_MEM(0)->set_monitor(BX_CPU_THIS_PTR bx_cpuid);
#else #else
BX_INFO(("MONITOR: use --enable-monitor-mwait to enable MONITOR/MWAIT support")); BX_INFO(("MONITOR: use --enable-monitor-mwait to enable MONITOR/MWAIT support"));
exception(BX_UD_EXCEPTION, 0, 0); exception(BX_UD_EXCEPTION, 0, 0);
@ -2005,11 +2013,11 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MWAIT(bxInstruction_c *i)
return; return;
} }
bx_pc_system.invlpg(BX_CPU_THIS_PTR monitor.monitor_begin); // If monitor has already triggered, we just return.
if ((BX_CPU_THIS_PTR monitor.monitor_end & ~0xfff) != (BX_CPU_THIS_PTR monitor.monitor_begin & ~0xfff)) if (!BX_CPU_THIS_PTR monitor.armed) {
bx_pc_system.invlpg(BX_CPU_THIS_PTR monitor.monitor_end); BX_DEBUG(("MWAIT: the MONITOR was already triggered"));
BX_DEBUG(("MWAIT for phys_addr=" FMT_PHY_ADDRX, BX_CPU_THIS_PTR monitor.monitor_begin)); return;
BX_MEM(0)->set_monitor(BX_CPU_THIS_PTR bx_cpuid); }
// stops instruction execution and places the processor in a optimized // stops instruction execution and places the processor in a optimized
// state. Events that cause exit from MWAIT state are: // state. Events that cause exit from MWAIT state are: