Make it compilable in 32 and 64 bit mode. --- config-x86-common.mak | 7 +- lib/x86/idt.c | 32 ++++------- lib/x86/idt.h | 1 + x86/idt.c | 148 ------------------------------------------------- 4 files changed, 16 insertions(+), 172 deletions(-) delete mode 100644 x86/idt.c diff --git a/config-x86-common.mak b/config-x86-common.mak index c5508b3..2269c4a 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -11,6 +11,7 @@ cflatobjs += \ cflatobjs += lib/x86/fwcfg.o cflatobjs += lib/x86/apic.o cflatobjs += lib/x86/atomic.o +cflatobjs += lib/x86/idt.o $(libcflat): LDFLAGS += -nostdlib $(libcflat): CFLAGS += -ffreestanding -I lib @@ -50,7 +51,7 @@ $(TEST_DIR)/vmexit.elf: $(cstart.o) $(TEST_DIR)/vmexit.o $(TEST_DIR)/smptest.elf: $(cstart.o) $(TEST_DIR)/smptest.o $(TEST_DIR)/emulator.elf: $(cstart.o) $(TEST_DIR)/emulator.o \ - $(TEST_DIR)/vm.o $(TEST_DIR)/idt.o + $(TEST_DIR)/vm.o $(TEST_DIR)/port80.elf: $(cstart.o) $(TEST_DIR)/port80.o @@ -65,9 +66,9 @@ $(TEST_DIR)/realmode.o: bits = 32 $(TEST_DIR)/msr.elf: $(cstart.o) $(TEST_DIR)/msr.o -$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/idt_test.o +$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt_test.o -$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/xsave.o +$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/xsave.o $(TEST_DIR)/rmap_chain.elf: $(cstart.o) $(TEST_DIR)/rmap_chain.o \ $(TEST_DIR)/vm.o diff --git a/lib/x86/idt.c b/lib/x86/idt.c index ed2f4b0..b3e47d4 100644 --- a/lib/x86/idt.c +++ b/lib/x86/idt.c @@ -1,5 +1,6 @@ #include "idt.h" #include "libcflat.h" +#include "processor.h" typedef struct { unsigned short offset0; @@ -19,30 +20,19 @@ typedef struct { static idt_entry_t idt[256]; -typedef struct { - unsigned short limit; - unsigned long linear_addr; -} __attribute__((packed)) descriptor_table_t; - -void lidt(idt_entry_t *idt, int nentries) +void load_lidt(idt_entry_t *idt, int nentries) { - descriptor_table_t dt; + struct descriptor_table_ptr dt; dt.limit = nentries * sizeof(*idt) - 1; - dt.linear_addr = (unsigned long)idt; + dt.base = (unsigned long)idt; + lidt(&dt); asm volatile ("lidt %0" : : "m"(dt)); } -unsigned short read_cs() -{ - unsigned short r; - - asm volatile ("mov %%cs, %0" : "=r"(r)); - return r; -} - -void set_idt_entry(idt_entry_t *e, void *addr, int dpl) +void set_idt_entry(int vec, void *addr, int dpl) { + idt_entry_t *e = &idt[vec]; memset(e, 0, sizeof *e); e->offset0 = (unsigned long)addr; e->selector = read_cs(); @@ -146,10 +136,10 @@ void setup_idt(void) { extern char ud_fault, gp_fault, de_fault; - lidt(idt, 256); - set_idt_entry(&idt[0], &de_fault, 0); - set_idt_entry(&idt[6], &ud_fault, 0); - set_idt_entry(&idt[13], &gp_fault, 0); + load_lidt(idt, 256); + set_idt_entry(0, &de_fault, 0); + set_idt_entry(6, &ud_fault, 0); + set_idt_entry(13, &gp_fault, 0); } unsigned exception_vector(void) diff --git a/lib/x86/idt.h b/lib/x86/idt.h index 6babcb4..81b8944 100644 --- a/lib/x86/idt.h +++ b/lib/x86/idt.h @@ -15,5 +15,6 @@ void setup_idt(void); unsigned exception_vector(void); unsigned exception_error_code(void); +void set_idt_entry(int vec, void *addr, int dpl); #endif diff --git a/x86/idt.c b/x86/idt.c deleted file mode 100644 index 4480833..0000000 --- a/x86/idt.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "idt.h" -#include "libcflat.h" - -typedef struct { - unsigned short offset0; - unsigned short selector; - unsigned short ist : 3; - unsigned short : 5; - unsigned short type : 4; - unsigned short : 1; - unsigned short dpl : 2; - unsigned short p : 1; - unsigned short offset1; - unsigned offset2; - unsigned reserved; -} idt_entry_t; - -static idt_entry_t idt[256]; - -typedef struct { - unsigned short limit; - unsigned long linear_addr; -} __attribute__((packed)) descriptor_table_t; - -void lidt(idt_entry_t *idt, int nentries) -{ - descriptor_table_t dt; - - dt.limit = nentries * sizeof(*idt) - 1; - dt.linear_addr = (unsigned long)idt; - asm volatile ("lidt %0" : : "m"(dt)); -} - -unsigned short read_cs() -{ - unsigned short r; - - asm volatile ("mov %%cs, %0" : "=r"(r)); - return r; -} - -void set_idt_entry(idt_entry_t *e, void *addr, int dpl) -{ - memset(e, 0, sizeof *e); - e->offset0 = (unsigned long)addr; - e->selector = read_cs(); - e->ist = 0; - e->type = 14; - e->dpl = dpl; - e->p = 1; - e->offset1 = (unsigned long)addr >> 16; - e->offset2 = (unsigned long)addr >> 32; -} - -struct ex_regs { - unsigned long rax, rcx, rdx, rbx; - unsigned long dummy, rbp, rsi, rdi; - unsigned long r8, r9, r10, r11; - unsigned long r12, r13, r14, r15; - unsigned long vector; - unsigned long error_code; - unsigned long rip; - unsigned long cs; - unsigned long rflags; -}; - -struct ex_record { - unsigned long rip; - unsigned long handler; -}; - -extern struct ex_record exception_table_start, exception_table_end; - -void do_handle_exception(struct ex_regs *regs) -{ - struct ex_record *ex; - unsigned ex_val; - - ex_val = regs->vector | (regs->error_code << 16); - - asm("mov %0, %%gs:4" : : "r"(ex_val)); - - for (ex = &exception_table_start; ex != &exception_table_end; ++ex) { - if (ex->rip == regs->rip) { - regs->rip = ex->handler; - return; - } - } - printf("unhandled excecption\n"); - exit(7); -} - -asm (".pushsection .text \n\t" - "ud_fault: \n\t" - "pushq $0 \n\t" - "pushq $6 \n\t" - "jmp handle_exception \n\t" - - "gp_fault: \n\t" - "pushq $13 \n\t" - "jmp handle_exception \n\t" - - "de_fault: \n\t" - "pushq $0 \n\t" - "pushq $0 \n\t" - "jmp handle_exception \n\t" - - "handle_exception: \n\t" - "push %r15; push %r14; push %r13; push %r12 \n\t" - "push %r11; push %r10; push %r9; push %r8 \n\t" - "push %rdi; push %rsi; push %rbp; sub $8, %rsp \n\t" - "push %rbx; push %rdx; push %rcx; push %rax \n\t" - "mov %rsp, %rdi \n\t" - "call do_handle_exception \n\t" - "pop %rax; pop %rcx; pop %rdx; pop %rbx \n\t" - "add $8, %rsp; pop %rbp; pop %rsi; pop %rdi \n\t" - "pop %r8; pop %r9; pop %r10; pop %r11 \n\t" - "pop %r12; pop %r13; pop %r14; pop %r15 \n\t" - "add $16, %rsp \n\t" - "iretq \n\t" - ".popsection"); - - -void setup_idt(void) -{ - extern char ud_fault, gp_fault, de_fault; - - lidt(idt, 256); - set_idt_entry(&idt[0], &de_fault, 0); - set_idt_entry(&idt[6], &ud_fault, 0); - set_idt_entry(&idt[13], &gp_fault, 0); -} - -unsigned exception_vector(void) -{ - unsigned short vector; - - asm("mov %%gs:4, %0" : "=rm"(vector)); - return vector; -} - -unsigned exception_error_code(void) -{ - unsigned short error_code; - - asm("mov %%gs:6, %0" : "=rm"(error_code)); - return error_code; -} -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html