minor improvements and cosmetic changes to increase the readability

This commit is contained in:
Stefan Lankes 2011-04-05 02:00:02 -07:00
parent 9918db81ec
commit e8abd6f336
2 changed files with 45 additions and 10 deletions

View file

@ -36,6 +36,7 @@ extern "C" {
#define APIC_ICR1 0x0300 // Interrupt Command Register [0-31]
#define APIC_ICR2 0x0310 // Interrupt Command Register [32-63]
#define APIC_LVT_T 0x0320 // LVT Timer Register
#define APIC_LVT_TSR 0x0330 // LVT Thermal Sensor Register
#define APIC_LVT_PMC 0x0340 // LVT Performance Monitoring Counters Register
#define APIC_LINT0 0x0350 // LVT LINT0 Register
#define APIC_LINT1 0x0360 // LVT LINT1 Register

View file

@ -76,6 +76,7 @@ static inline void lapic_write(uint32_t addr, uint32_t value)
* to avoid a pentium bug, we have to read a apic register
* before we write a value to this register
*/
//asm volatile ("cmpl (%0), %%eax; movl %1, (%0)" :: "r"(lapic+addr), "r"(value));
asm volatile ("movl (%%eax), %%edx; movl %%ebx, (%%eax)" :: "a"(lapic+addr), "b"(value) : "%edx");
//*((volatile uint32_t*) (lapic+addr)) = value;
}
@ -109,6 +110,26 @@ uint32_t apic_cpu_id(void)
return 0;
}
static inline uint32_t apic_version(void)
{
if (lapic) {
uint32_t i = *((uint32_t*) (lapic+APIC_VERSION));
return i & 0xFF;
}
return 0;
}
static inline uint32_t apic_lvt_entries(void)
{
if (lapic) {
uint32_t i = *((uint32_t*) (lapic+APIC_VERSION));
return (i >> 16) & 0xFF;
}
return 0;
}
int has_apic(void)
{
return (lapic != 0);
@ -276,10 +297,11 @@ int apic_calibration(void)
;
diff = 0xFFFFFFFF - lapic_read(APIC_CCR);
diff = diff / 3;
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 / 3);
lapic_write(APIC_ICR, diff);
// Now, MetalSVM is able to use the APIC => Therefore, we disable the PIC
outportb(0xA1, 0xFF);
@ -316,13 +338,14 @@ int apic_calibration(void)
} while(ticks*TIMER_FREQ < 3*RC_REFCLOCKMHZ*1000000);
diff = 0xFFFFFFFF - lapic_read(APIC_CCR);
diff = diff / 3;
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 / 3);
lapic_write(APIC_ICR, diff);
#endif
kprintf("APIC calibration determines an ICR of 0x%x\n", diff / 3);
kprintf("APIC calibration determines an ICR of 0x%x\n", diff);
flags = irq_nested_disable();
#if MAX_CORES > 1
@ -471,16 +494,20 @@ check_lapic:
if (!lapic)
goto out;
i = *((uint32_t*) (lapic+APIC_VERSION));
kprintf("Found APIC at 0x%x\n", lapic);
kprintf("Maximum LVT Entry: 0x%x\n", (i >> 16) & 0xFF);
kprintf("APIC Version: 0x%x\n", i & 0xFF);
kprintf("Maximum LVT Entry: 0x%x\n", apic_lvt_entries());
kprintf("APIC Version: 0x%x\n", apic_version());
if (!((i & 0xFF) >> 4)) {
if (!((apic_version() >> 4))) {
kprintf("Currently, MetalSVM didn't supports extern APICs!\n");
goto out;
}
if (apic_lvt_entries() < 3) {
kprintf("LVT is too small\n");
goto out;
}
return 0;
out:
@ -501,18 +528,25 @@ int apic_init(void)
{
int ret;
uint8_t i;
uint32_t v;
uint32_t max_lvt;
ret = apic_probe();
if (!ret)
return ret;
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
lapic_write(APIC_LVT_PMC, 0x10000);// disable performance counter interrupt
if (max_lvt >= 4)
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_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_SVR, 0x17F); // enable the apic and connect to the idt entry 127
if (0) { //ioapic) {
// enable timer interrupt