use memory barriers instead of read memory barriers to determine the current TSC
=> more accurate caclculation of the timer frequency + minor cosmetic changes
This commit is contained in:
parent
624afd187c
commit
47f37e3b00
2 changed files with 22 additions and 17 deletions
|
@ -140,7 +140,7 @@ static inline void tlb_flush(void)
|
|||
static inline uint32_t read_eflags(void)
|
||||
{
|
||||
uint32_t result;
|
||||
asm volatile ("pushf; popl %%eax" : "=a"(result) :: "memory");
|
||||
asm volatile ("pushf; pop %%eax" : "=a"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ static apic_mp_t* apic_mp = NULL;
|
|||
static apic_config_table_t* apic_config = NULL;
|
||||
static uint32_t lapic = 0;
|
||||
static volatile ioapic_t* ioapic = NULL;
|
||||
static uint32_t icr = 0;
|
||||
static uint32_t ncores = 1;
|
||||
static uint8_t irq_redirect[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
|
||||
#if MAX_CORES > 1
|
||||
|
@ -256,19 +257,28 @@ int smp_init(void)
|
|||
|
||||
static int lapic_reset(void)
|
||||
{
|
||||
uint32_t max_lvt = apic_lvt_entries();
|
||||
uint32_t max_lvt;
|
||||
|
||||
if (!lapic)
|
||||
return -ENXIO;
|
||||
|
||||
max_lvt = apic_lvt_entries();
|
||||
|
||||
lapic_write(APIC_SVR, 0x17F); // enable the apic and connect to the idt entry 127
|
||||
lapic_write(APIC_TPR, 0x00); // allow all interrupts
|
||||
lapic_write(APIC_LVT_T, 0x10000); // disable timer interrupt
|
||||
if (icr) {
|
||||
lapic_write(APIC_DCR, 0xB); // set it to 1 clock increments
|
||||
lapic_write(APIC_LVT_T, 0x2007B); // connects the timer to 123 and enables it
|
||||
lapic_write(APIC_ICR, icr);
|
||||
} else
|
||||
lapic_write(APIC_LVT_T, 0x10000); // disable timer interrupt
|
||||
if (max_lvt >= 4)
|
||||
lapic_write(APIC_LVT_TSR, 0x10000); // disable thermal sensor interrupt
|
||||
lapic_write(APIC_LVT_TSR, 0x10000); // disable thermal sensor interrupt
|
||||
if (max_lvt >= 5)
|
||||
lapic_write(APIC_LVT_PMC, 0x10000); // disable performance counter interrupt
|
||||
lapic_write(APIC_LVT_PMC, 0x10000); // disable performance counter interrupt
|
||||
lapic_write(APIC_LINT0, 0x7C); // connect LINT0 to idt entry 124
|
||||
lapic_write(APIC_LINT1, 0x7D); // connect LINT1 to idt entry 125
|
||||
lapic_write(APIC_LVT_ER, 0x7E); // connect error to idt entry 126
|
||||
lapic_write(APIC_ID, 0x00); // reset boot processor id
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -328,13 +338,10 @@ int apic_calibration(void)
|
|||
HALT;
|
||||
|
||||
diff = 0xFFFFFFFFUL - lapic_read(APIC_CCR);
|
||||
diff = diff / 3;
|
||||
icr = diff / 3;
|
||||
|
||||
flags = irq_nested_disable();
|
||||
lapic_reset();
|
||||
lapic_write(APIC_DCR, 0xB); // set it to 1 clock increments
|
||||
lapic_write(APIC_LVT_T, 0x2007B); // connects the timer to 123 and enables it
|
||||
lapic_write(APIC_ICR, diff);
|
||||
irq_nested_enable(flags);
|
||||
|
||||
// Now, MetalSVM is able to use the APIC => Therefore, we disable the PIC
|
||||
|
@ -353,26 +360,23 @@ int apic_calibration(void)
|
|||
lapic_write(APIC_ICR, 0xFFFFFFFFUL);
|
||||
|
||||
/* wait 3 time slices to determine a ICR */
|
||||
rmb();
|
||||
mb();
|
||||
start = rdtsc();
|
||||
do {
|
||||
rmb();
|
||||
mb();
|
||||
end = rdtsc();
|
||||
ticks = end > start ? end - start : start - end;
|
||||
} while(ticks*TIMER_FREQ < 3*RC_REFCLOCKMHZ*1000000UL);
|
||||
|
||||
diff = 0xFFFFFFFFUL - lapic_read(APIC_CCR);
|
||||
diff = diff / 3;
|
||||
icr = diff / 3;
|
||||
|
||||
lapic_reset();
|
||||
lapic_write(APIC_DCR, 0xB); // set it to 1 clock increments
|
||||
lapic_write(APIC_LVT_T, 0x2007B); // connects the timer to 123 and enables it
|
||||
lapic_write(APIC_ICR, diff);
|
||||
|
||||
irq_nested_enable(flags);
|
||||
#endif
|
||||
|
||||
kprintf("APIC calibration determines an ICR of 0x%x\n", diff);
|
||||
kprintf("APIC calibration determines an ICR of 0x%x\n", icr);
|
||||
|
||||
flags = irq_nested_disable();
|
||||
#if MAX_CORES > 1
|
||||
|
@ -568,6 +572,7 @@ int apic_init(void)
|
|||
// set APIC error handler
|
||||
irq_install_handler(126, apic_err_handler);
|
||||
|
||||
// initialize local apic
|
||||
ret = lapic_reset();
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
|
Loading…
Add table
Reference in a new issue