Commit 23ba7b39 authored by Gleb Natapov's avatar Gleb Natapov Committed by Avi Kivity
Browse files

Move idt.c into lib code



Make it compilable in 32 and 64 bit mode.
Signed-off-by: default avatarGleb Natapov <gleb@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent fd5d3dc6
......@@ -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
......@@ -53,7 +54,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
......@@ -68,9 +69,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
......
#include "idt.h"
#include "libcflat.h"
#include "processor.h"
typedef struct {
unsigned short offset0;
......@@ -11,36 +12,27 @@ typedef struct {
unsigned short dpl : 2;
unsigned short p : 1;
unsigned short offset1;
#ifdef __x86_64__
unsigned offset2;
unsigned reserved;
#endif
} 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)
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();
......@@ -49,14 +41,18 @@ void set_idt_entry(idt_entry_t *e, void *addr, int dpl)
e->dpl = dpl;
e->p = 1;
e->offset1 = (unsigned long)addr >> 16;
#ifdef __x86_64__
e->offset2 = (unsigned long)addr >> 32;
#endif
}
struct ex_regs {
unsigned long rax, rcx, rdx, rbx;
unsigned long dummy, rbp, rsi, rdi;
#ifdef __x86_64__
unsigned long r8, r9, r10, r11;
unsigned long r12, r13, r14, r15;
#endif
unsigned long vector;
unsigned long error_code;
unsigned long rip;
......@@ -90,34 +86,49 @@ void do_handle_exception(struct ex_regs *regs)
exit(7);
}
#ifdef __x86_64__
# define R "r"
# define W "q"
# define S "8"
#else
# define R "e"
# define W "l"
# define S "4"
#endif
asm (".pushsection .text \n\t"
"ud_fault: \n\t"
"pushq $0 \n\t"
"pushq $6 \n\t"
"push"W" $0 \n\t"
"push"W" $6 \n\t"
"jmp handle_exception \n\t"
"gp_fault: \n\t"
"pushq $13 \n\t"
"push"W" $13 \n\t"
"jmp handle_exception \n\t"
"de_fault: \n\t"
"pushq $0 \n\t"
"pushq $0 \n\t"
"push"W" $0 \n\t"
"push"W" $0 \n\t"
"jmp handle_exception \n\t"
"handle_exception: \n\t"
#ifdef __x86_64__
"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"
#endif
"push %"R"di; push %"R"si; push %"R"bp; sub $"S", %"R"sp \n\t"
"push %"R"bx; push %"R"dx; push %"R"cx; push %"R"ax \n\t"
"mov %"R"sp, %"R"di \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 %"R"ax; pop %"R"cx; pop %"R"dx; pop %"R"bx \n\t"
"add $"S", %"R"sp; pop %"R"bp; pop %"R"si; pop %"R"di \n\t"
#ifdef __x86_64__
"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"
#endif
"add $"S", %"R"sp \n\t"
"add $"S", %"R"sp \n\t"
"iret"W" \n\t"
".popsection");
......@@ -125,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)
......
......@@ -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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment