From 03162d86f59e814137f212ad5c232f6a16c01e97 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Sat, 12 May 2012 11:52:29 +0000 Subject: [PATCH] LAPIC: fixed timer interrupts after reloading of LAPIC Timer Divide Configuration register --- bochs/CHANGES | 1 + bochs/cpu/apic.cc | 24 +++++++++++++----------- bochs/gui/enh_dbg.cc | 22 ++++++++++++---------- bochs/iodev/ioapic.cc | 2 ++ 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/bochs/CHANGES b/bochs/CHANGES index 82036b61f..2a7ae85f7 100644 --- a/bochs/CHANGES +++ b/bochs/CHANGES @@ -15,6 +15,7 @@ Changes after 2.5.1 release: ! Added AMD Phenom X3 8650 (Toliman) configuration to the CPUDB ! Added Corei7 3770K (Ivy Bridge) configuration to the CPUDB - Bugfixes for CPU emulation correctness and stability + (critical fixes for VMX and XOP emulation) - Bochs Debugger and Instrumentation - Implemented new debugger command 'info device [string]' that shows the diff --git a/bochs/cpu/apic.cc b/bochs/cpu/apic.cc index a9fd2dc13..5ffe32fd1 100644 --- a/bochs/cpu/apic.cc +++ b/bochs/cpu/apic.cc @@ -1077,20 +1077,23 @@ void bx_local_apic_c::periodic(void) Bit32u timervec = lvt[APIC_LVT_TIMER]; - // If timer is not masked, trigger interrupt. - if((timervec & 0x10000)==0) { - trigger_irq(timervec & 0xff, APIC_EDGE_TRIGGERED); - } - else { - BX_DEBUG(("local apic timer LVT masked")); - } + // If timer is not masked, trigger interrupt + if((timervec & 0x10000)==0) { + trigger_irq(timervec & 0xff, APIC_EDGE_TRIGGERED); + } + else { + BX_DEBUG(("local apic timer LVT masked")); + } - // timer reached zero since the last call to periodic. + // timer reached zero since the last call to periodic if(timervec & 0x20000) { // Periodic mode - reload timer values timer_current = timer_initial; + timer_active = 1; ticksInitial = bx_pc_system.time_ticks(); // timer value when it started to count BX_DEBUG(("local apic timer(periodic) triggered int, reset counter to 0x%08x", timer_current)); + bx_pc_system.activate_timer_ticks(timer_handle, + Bit64u(timer_initial) * Bit64u(timer_divide_factor), 0); } else { // one-shot mode @@ -1104,7 +1107,7 @@ void bx_local_apic_c::periodic(void) void bx_local_apic_c::set_divide_configuration(Bit32u value) { BX_ASSERT(value == (value & 0x0b)); - // move bit 3 down to bit 0. + // move bit 3 down to bit 0 value = ((value & 8) >> 1) | (value & 3); BX_ASSERT(value >= 0 && value <= 7); timer_divide_factor = (value==7) ? 1 : (2 << value); @@ -1136,10 +1139,9 @@ void bx_local_apic_c::set_initial_timer_count(Bit32u value) BX_DEBUG(("APIC: Initial Timer Count Register = %u", value)); timer_current = timer_initial; timer_active = 1; - bx_bool continuous = (timervec & 0x20000) > 0; ticksInitial = bx_pc_system.time_ticks(); // timer value when it started to count bx_pc_system.activate_timer_ticks(timer_handle, - Bit64u(timer_initial) * Bit64u(timer_divide_factor), continuous); + Bit64u(timer_initial) * Bit64u(timer_divide_factor), 0); } } diff --git a/bochs/gui/enh_dbg.cc b/bochs/gui/enh_dbg.cc index 410819453..87ca99ced 100644 --- a/bochs/gui/enh_dbg.cc +++ b/bochs/gui/enh_dbg.cc @@ -274,7 +274,7 @@ int DoMatch(const char *text, const char *p, bx_bool IsCaseSensitive) // NO BREAK HERE default: - if (IsCaseSensitive != FALSE) + if (IsCaseSensitive) { if (text[pT] != p[pP]) return MATCH_FALSE; @@ -1000,7 +1000,7 @@ void LoadRegList() cols[1] = regtxt; cols[2] = regtxt + 40; itemnum = 0; - if (In64Mode != FALSE) + if (In64Mode) { showEreg = SeeReg[0]; // get user option setting for EAX, etc. for (i = RAX_Rnum; i <= R15_Rnum; i++) @@ -1978,7 +1978,7 @@ void FillDataX(char* t, char C, bx_bool doHex) *d = AsciiHex[2* (unsigned char)C]; d[1] = AsciiHex[2* (unsigned char)C + 1]; d[2] = 0; - if (isLittleEndian != FALSE) // little endian => reverse hex digits + if (isLittleEndian) // little endian => reverse hex digits { strcat(d,t); strcpy(t,d); // so append the new bytes to the FRONT of t @@ -2206,7 +2206,7 @@ void OnBreak() In32Mode = d_b; } } - if (CpuModeChange != FALSE) + if (CpuModeChange) { GrayMenuItem ((int) In64Mode, CMD_EREG); BottomAsmLA = ~0; // force an ASM autoload @@ -2285,20 +2285,21 @@ bx_bool InitDataDump(bx_bool isLinear, Bit64u newDS) } // load 4k DataDump array from bochs emulated linear or physical memory - if (isLinear != FALSE) + if (isLinear) { // cannot read linear mem across a 4K boundary -- so break the read in two // -- calculate location of 4K boundary (h): - unsigned int len = (int) newDS & 0xfff; - unsigned int i = 4096 - len; + unsigned len = (int) newDS & 0xfff; + unsigned i = 4096 - len; Bit64u h = newDS + i; retval = ReadBxLMem(newDS,i,(Bit8u *)DataDump); if (retval != FALSE && len != 0) retval = ReadBxLMem(h,len,(Bit8u *)DataDump + i); } - else - retval = (bx_bool) bx_mem.dbg_fetch_mem( BX_CPU(CurrentCPU), + else { + retval = (bx_bool) bx_mem.dbg_fetch_mem(BX_CPU(CurrentCPU), (bx_phy_address)newDS, 4096, (Bit8u *)DataDump); + } if (retval == FALSE) { // assume that the DataDump array is still valid -- fetch_mem should error without damage @@ -2306,6 +2307,7 @@ bx_bool InitDataDump(bx_bool isLinear, Bit64u newDS) DispMessage ("Address range was not legal memory","Memory Error"); return retval; } + SA_valid = FALSE; // any previous MemDump click is now irrelevant ResizeColmns = TRUE; // autosize column 0 once DumpInitted = TRUE; // OK to refresh the Dump window in the future (it has data) @@ -2721,7 +2723,7 @@ void SetMemLine(int L) char *x = tmpcb; upr(x); // force input string to uppercase - if (LinearDump != FALSE) // is h is a LINEAR address? Convert to physical! + if (LinearDump) // is h is a LINEAR address? Convert to physical! { // use the ReadBx function to calculate the lin->phys offset if (ReadBxLMem(h,0,(Bit8u *)addrstr) == FALSE) // "read" 0 bytes diff --git a/bochs/iodev/ioapic.cc b/bochs/iodev/ioapic.cc index d04da86d3..969daf2a8 100644 --- a/bochs/iodev/ioapic.cc +++ b/bochs/iodev/ioapic.cc @@ -222,9 +222,11 @@ void bx_ioapic_c::write_aligned(bx_phy_address address, Bit32u value) void bx_ioapic_c::set_irq_level(Bit8u int_in, bx_bool level) { +/* if (int_in == 0) { // timer connected to pin #2 int_in = 2; } +*/ BX_DEBUG(("set_irq_level(): INTIN%d: level=%d", int_in, level)); if (int_in < BX_IOAPIC_NUM_PINS) { Bit32u bit = 1<