LAPIC: fixed timer interrupts after reloading of LAPIC Timer Divide Configuration register

This commit is contained in:
Stanislav Shwartsman 2012-05-12 11:52:29 +00:00
parent 3202afb48e
commit 03162d86f5
4 changed files with 28 additions and 21 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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<<int_in;