LAPIC: fixed timer interrupts after reloading of LAPIC Timer Divide Configuration register
This commit is contained in:
parent
3202afb48e
commit
03162d86f5
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user