From a9c4b5ddc0a4e3fc363471295395984715bfb841 Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Tue, 19 Apr 2011 18:51:59 +0200 Subject: [PATCH] Encapsulated IDT-/GDT-descriptor configuring code into helper functions. --- arch/x86/include/asm/gdt.h | 10 ++++++++++ arch/x86/include/asm/idt.h | 10 ++++++++++ arch/x86/kernel/gdt.c | 22 +++++++++++++++------- arch/x86/kernel/idt.c | 19 ++++++++++++++----- 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/gdt.h b/arch/x86/include/asm/gdt.h index cdb65d46..fb4bd4c1 100644 --- a/arch/x86/include/asm/gdt.h +++ b/arch/x86/include/asm/gdt.h @@ -115,6 +115,16 @@ typedef struct { */ void gdt_install(void); +/** @brief Configures and returns a GDT descriptor with chosen attributes + * + * Just feed this function with address, limit and the flags + * you have seen in idt.h + * + * @return a preconfigured gdt descriptor + */ +gdt_entry_t configure_gdt_entry(unsigned long base, unsigned long limit, + unsigned char access, unsigned char gran); + #ifdef __cplusplus } #endif diff --git a/arch/x86/include/asm/idt.h b/arch/x86/include/asm/idt.h index a43d4383..28fde65a 100644 --- a/arch/x86/include/asm/idt.h +++ b/arch/x86/include/asm/idt.h @@ -116,6 +116,16 @@ void idt_install(void); void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags); +/** @brief Configures and returns a IDT entry with chosen attributes + * + * Just feed this function with base, selector and the flags + * you have seen in idt.h + * + * @return a preconfigured idt descriptor + */ +idt_entry_t configure_idt_entry(unsigned long base, unsigned short sel, + unsigned char flags); + #ifdef __cplusplus } #endif diff --git a/arch/x86/kernel/gdt.c b/arch/x86/kernel/gdt.c index 33b136ee..5be409c6 100644 --- a/arch/x86/kernel/gdt.c +++ b/arch/x86/kernel/gdt.c @@ -157,19 +157,27 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg) static void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran) { + gdt[num] = configure_gdt_entry(base, limit, access, gran); +} +gdt_entry_t configure_gdt_entry(unsigned long base, unsigned long limit, + unsigned char access, unsigned char gran) +{ + gdt_entry_t desc; /* Setup the descriptor base address */ - gdt[num].base_low = (base & 0xFFFF); - gdt[num].base_middle = (base >> 16) & 0xFF; - gdt[num].base_high = (base >> 24) & 0xFF; + desc.base_low = (base & 0xFFFF); + desc.base_middle = (base >> 16) & 0xFF; + desc.base_high = (base >> 24) & 0xFF; /* Setup the descriptor limits */ - gdt[num].limit_low = (limit & 0xFFFF); - gdt[num].granularity = ((limit >> 16) & 0x0F); + desc.limit_low = (limit & 0xFFFF); + desc.granularity = ((limit >> 16) & 0x0F); /* Finally, set up the granularity and access flags */ - gdt[num].granularity |= (gran & 0xF0); - gdt[num].access = access; + desc.granularity |= (gran & 0xF0); + desc.access = access; + + return desc; } /* diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c index fd8156c4..fe3b2bf4 100644 --- a/arch/x86/kernel/idt.c +++ b/arch/x86/kernel/idt.c @@ -48,16 +48,25 @@ static idt_ptr_t idtp; void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags) { + idt[num] = configure_idt_entry(base, sel, flags); +} + +idt_entry_t configure_idt_entry(unsigned long base, unsigned short sel, + unsigned char flags) +{ + idt_entry_t desc; /* The interrupt routine's base address */ - idt[num].base_lo = (base & 0xFFFF); - idt[num].base_hi = (base >> 16) & 0xFFFF; + desc.base_lo = (base & 0xFFFF); + desc.base_hi = (base >> 16) & 0xFFFF; /* The segment or 'selector' that this IDT entry will use * is set here, along with any access flags */ - idt[num].sel = sel; - idt[num].always0 = 0; - idt[num].flags = flags; + desc.sel = sel; + desc.always0 = 0; + desc.flags = flags; + + return desc; } extern void isrsyscall(void);