minor improvements and cosmetic changes to increase the readability
This commit is contained in:
parent
9918db81ec
commit
e8abd6f336
2 changed files with 45 additions and 10 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue