123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- #include "apic.h"
- #include "../../../common/kprint.h"
- #include "../../../common/printk.h"
- #include "../../../common/cpu.h"
- #include "../../../common/glib.h"
- #include "../../../exception/gate.h"
- #include "../../acpi/acpi.h"
- extern void (*interrupt_table[24])(void);
- bool flag_support_apic = false;
- bool flag_support_x2apic = false;
- uint local_apic_version;
- uint local_apic_max_LVT_entries;
- static struct acpi_Multiple_APIC_Description_Table_t *madt;
- void apic_io_apic_init()
- {
-
- for (int i = 32; i <= 55; ++i)
- set_intr_gate(i, 2, interrupt_table[i - 32]);
-
- io_out8(0x21, 0xff);
- io_out8(0xa1, 0xff);
- kdebug("8259A Masked.");
- ul madt_addr;
- kdebug("madt_addr = %#018lx", (ul)madt_addr);
- acpi_iter_SDT(acpi_get_MADT, &madt_addr);
- madt = (struct acpi_Multiple_APIC_Description_Table_t *)madt_addr;
- kdebug("MADT->local intr controller addr=%#018lx", madt->Local_Interrupt_Controller_Address);
- kdebug("MADT->length= %d bytes", madt->header.Length);
- void *ent = (void *)(madt_addr) + sizeof(struct acpi_Multiple_APIC_Description_Table_t);
- struct apic_Interrupt_Controller_Structure_header_t *header;
- for (int i = 0; i < 17; ++i)
- {
- header = (struct apic_Interrupt_Controller_Structure_header_t *)ent;
- kdebug("[ %d ] type=%d, length=%d", i, header->type, header->length);
- if (header->type == 1)
- {
- struct acpi_IO_APIC_Structure_t *t = (struct acpi_IO_APIC_Structure_t *)ent;
- kdebug("IO apic addr = %#018lx", t->IO_APIC_Address);
- }
- ent += header->length;
- }
- apic_local_apic_init();
- sti();
- }
- void apic_local_apic_init()
- {
- uint a, b, c, d;
- cpu_cpuid(1, 0, &a, &b, &c, &d);
- kdebug("CPUID 0x01, eax:%#010lx, ebx:%#010lx, ecx:%#010lx, edx:%#010lx", a, b, c, d);
-
- if ((1 << 9) & d)
- {
- flag_support_apic = true;
- kdebug("This computer support APIC&xAPIC");
- }
- else
- {
- flag_support_apic = false;
- kerror("This computer does not support APIC&xAPIC");
- while (1)
- ;
- }
-
- if ((1 << 21) & c)
- {
- flag_support_x2apic = true;
- kdebug("This computer support x2APIC");
- }
- else
- {
- kerror("This computer does not support x2APIC");
- }
- uint eax, edx;
-
- __asm__ __volatile__("movq $0x1b, %%rcx \n\t"
- "rdmsr \n\t"
- "bts $10, %%rax \n\t"
- "bts $11, %%rax \n\t"
- "wrmsr \n\t"
- "movq $0x1b, %%rcx \n\t"
- "rdmsr \n\t"
- : "=a"(eax), "=d"(edx)::"memory");
- kdebug("After enable xAPIC and x2APIC: edx=%#010x, eax=%#010x", edx, eax);
-
- if (eax & 0xc00)
- kinfo("xAPIC & x2APIC enabled!");
-
- __asm__ __volatile__("movq 0x80f, %%rcx \n\t"
- "rdmsr \n\t"
- "bts $8, %%rax \n\t"
- "bts $12, %%rax \n\t"
- "movq 0x80f, %%rcx \n\t"
- "wrmsr \n\t"
- "movq $0x80f , %%rcx \n\t"
- "rdmsr \n\t"
- : "=a"(eax), "=d"(edx)::"memory", "rcx");
-
- kdebug("After setting SVR: edx=%#010x, eax=%#010x", edx, eax);
- if (eax & 0x100)
- kinfo("APIC Software Enabled.");
- if (eax & 0x1000)
- kinfo("EOI-Broadcast Suppression Enabled.");
-
-
-
-
- __asm__ __volatile__("movq $0x802, %%rcx \n\t"
- "rdmsr \n\t"
- : "=a"(eax), "=d"(edx)::"memory");
- kdebug("get Local APIC ID: edx=%#010x, eax=%#010x", edx, eax);
-
-
- __asm__ __volatile__("movq $0x803, %%rcx \n\t"
- "rdmsr \n\t"
- : "=a"(eax), "=d"(edx)::"memory");
- local_apic_max_LVT_entries = ((eax >> 16) & 0xff) + 1;
- local_apic_version = eax & 0xff;
- kdebug("local APIC Version:%#010x,Max LVT Entry:%#010x,SVR(Suppress EOI Broadcast):%#04x\t", local_apic_version, local_apic_max_LVT_entries, (eax >> 24) & 0x1);
- if ((eax & 0xff) < 0x10)
- {
- kdebug("82489DX discrete APIC");
- }
- else if (((eax & 0xff) >= 0x10) && ((eax & 0xff) <= 0x15))
- kdebug("Integrated APIC.");
-
- __asm__ __volatile__(
- "movq $0x82f, %%rcx \n\t"
- "wrmsr \n\t"
- "movq $0x832, %%rcx \n\t"
- "wrmsr \n\t"
- "movq $0x833, %%rcx \n\t"
- "wrmsr \n\t"
- "movq $0x834, %%rcx \n\t"
- "wrmsr \n\t"
- "movq $0x835, %%rcx \n\t"
- "wrmsr \n\t"
- "movq $0x836, %%rcx \n\t"
- "wrmsr \n\t"
- "movq $0x837, %%rcx \n\t"
- "wrmsr \n\t"
- :
- : "a"(0x10000), "d"(0x00)
- : "memory");
- kdebug("All LVT Masked");
-
- __asm__ __volatile__("movq $0x808, %%rcx \n\t"
- "rdmsr \n\t"
- : "=a"(eax), "=d"(edx)::"memory");
- kdebug("LVT_TPR=%#010x", eax);
-
- __asm__ __volatile__("movq $0x80a, %%rcx \n\t"
- "rdmsr \n\t"
- : "=a"(eax), "=d"(edx)::"memory");
- kdebug("LVT_PPR=%#010x", eax);
- }
- void apic_init()
- {
- apic_io_apic_init();
- }
- void do_IRQ(struct pt_regs *rsp, ul number)
- {
- }
|