MONITOR/MWAIT: Do monitor on cache line granularity only + bugfix with possible TLB caching of monitored line

This commit is contained in:
Stanislav Shwartsman 2011-07-18 21:44:22 +00:00
parent f81e47cca2
commit cddd1e3758
3 changed files with 16 additions and 21 deletions

View File

@ -839,16 +839,14 @@ typedef struct {
#if BX_SUPPORT_MONITOR_MWAIT
struct monitor_addr_t {
bx_phy_address monitor_begin;
bx_phy_address monitor_end;
bx_phy_address monitor_addr;
bx_bool armed;
monitor_addr_t():
monitor_begin(0xffffffff), monitor_end(0xffffffff), armed(0) {}
monitor_addr_t(): monitor_addr(0xffffffff), armed(0) {}
BX_CPP_INLINE void arm(bx_phy_address addr) {
monitor_begin = addr;
monitor_end = addr + CACHE_LINE_SIZE - 1;
// align to cache line
monitor_addr = addr & ~((bx_phy_address)(CACHE_LINE_SIZE - 1));
armed = 1;
}

View File

@ -541,9 +541,8 @@ void BX_CPU_C::register_state(void)
#endif
#if BX_SUPPORT_MONITOR_MWAIT
bx_list_c *monitor_list = new bx_list_c(cpu, "MONITOR", 3);
BXRS_HEX_PARAM_FIELD(monitor_list, begin_addr, monitor.monitor_begin);
BXRS_HEX_PARAM_FIELD(monitor_list, end_addr, monitor.monitor_end);
bx_list_c *monitor_list = new bx_list_c(cpu, "MONITOR", 2);
BXRS_HEX_PARAM_FIELD(monitor_list, monitor_addr, monitor.monitor_addr);
BXRS_PARAM_BOOL(monitor_list, armed, monitor.armed);
#endif
@ -1238,9 +1237,4 @@ void BX_CPU_C::assert_checks(void)
BX_PANIC(("assert_checks: TR is not TSS type !"));
}
}
#if BX_SUPPORT_MONITOR_MWAIT
if (BX_CPU_THIS_PTR monitor.monitor_end < BX_CPU_THIS_PTR monitor.monitor_begin)
BX_PANIC(("assert_checks: MONITOR range is not set correctly !"));
#endif
}

View File

@ -498,8 +498,11 @@ bx_bool BX_CPU_C::is_monitor(bx_phy_address begin_addr, unsigned len)
{
if (! BX_CPU_THIS_PTR monitor.armed) return 0;
bx_phy_address monitor_begin = BX_CPU_THIS_PTR monitor.monitor_addr;
bx_phy_address monitor_end = monitor_start + CACHE_LINE_SIZE - 1;
bx_phy_address end_addr = begin_addr + len;
if (begin_addr >= BX_CPU_THIS_PTR monitor.monitor_end || end_addr <= BX_CPU_THIS_PTR monitor.monitor_begin)
if (begin_addr >= monitor_end || end_addr <= monitor_begin)
return 0;
else
return 1;
@ -568,14 +571,14 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MONITOR(bxInstruction_c *i)
bx_phy_address paddr = translate_linear(laddr, USER_PL, BX_READ);
// Set the monitor immediately. If monitor is still armed when we MWAIT,
// 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_pc_system.invlpg(paddr);
BX_CPU_THIS_PTR monitor.arm(paddr);
BX_DEBUG(("MONITOR for phys_addr=0x" FMT_PHY_ADDRX, BX_CPU_THIS_PTR monitor.monitor_begin));
BX_DEBUG(("MONITOR for phys_addr=0x" FMT_PHY_ADDRX, BX_CPU_THIS_PTR monitor.monitor_addr));
#endif
BX_NEXT_INSTR(i);
@ -641,7 +644,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MWAIT(bxInstruction_c *i)
// will remain in a optimized state until one of the above
// conditions is met.
BX_INSTR_MWAIT(BX_CPU_ID, BX_CPU_THIS_PTR monitor.monitor_begin, CACHE_LINE_SIZE, ECX);
BX_INSTR_MWAIT(BX_CPU_ID, BX_CPU_THIS_PTR monitor.monitor_addr, CACHE_LINE_SIZE, ECX);
#if BX_USE_IDLE_HACK
bx_gui->sim_is_idle();