usage of 64bit TSS descriptors and some code cleanups

This commit is contained in:
Stefan Lankes 2012-06-11 16:16:35 +02:00
parent 4fb03cde20
commit e230fdcf15
7 changed files with 37 additions and 34 deletions

View file

@ -101,7 +101,12 @@ typedef struct {
} __attribute__ ((packed)) gdt_ptr_t;
/// Defines the maximum number of GDT entries
#define GDT_ENTRIES (5+MAX_TASKS)
#ifdef CONFIG_X86_32
#define GDT_ENTRIES (5+MAX_TASKS)
#else
// a TSS descriptor is twice larger than a code/data descriptor
#define GDT_ENTRIES (5+MAX_TASKS*2)
#endif
#if GDT_ENTRIES > 8192
#error Too many GDT entries!
#endif

View file

@ -77,9 +77,18 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg);
*
* @return
* - 0 on success
* - -EINVAL (-22) on failure
*/
int register_task(void);
static inline int register_task(void)
{
#ifdef CONFIG_X86_32
uint16_t sel = (CORE_ID+5) << 3;
#else
uint16_t sel = (CORE_ID*2+5) << 3;
#endif
asm volatile ("ltr %%ax" : : "a"(sel));
return 0;
}
/** @brief Jump back to user code
*

View file

@ -70,8 +70,7 @@ typedef struct {
uint64_t ist_rsp5;
uint64_t ist_rsp6;
uint64_t ist_rsp7;
uint32_t res4; // reserved entries
uint32_t res5; // reserved entries
uint32_t res4, res5; // reserved entries
uint16_t res6, bitmap;
#endif
} __attribute__ ((packed)) tss_t;

View file

@ -48,14 +48,6 @@ mboot:
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
; AOUT kludge - must be physical addresses. Make a note of these:
; The linker script fills in the data for these ones!
; dd mboot
; dd code
; dd bss
; dd end
; dd start
msg db "?ello from MetalSVM kernel!!", 0

View file

@ -29,7 +29,7 @@
gdt_ptr_t gp;
tss_t task_state_segments[MAX_CORES] __attribute__ ((aligned (PAGE_SIZE)));
static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE))) = {[0 ... MAX_TASKS-1][0 ... KERNEL_STACK_SIZE-1] = 0xCD};
size_t default_stack_pointer = (size_t) kstacks[0] + KERNEL_STACK_SIZE - sizeof(size_t);
size_t default_stack_pointer = (size_t) kstacks[0] + KERNEL_STACK_SIZE - 16; // => stack is 16byte aligned
// currently, our kernel has full access to the ioports
static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0}};
@ -52,17 +52,7 @@ size_t get_stack(uint32_t id)
{
if (BUILTIN_EXPECT(id >= MAX_TASKS, 0))
return -EINVAL;
return (size_t) kstacks[id] + KERNEL_STACK_SIZE - sizeof(size_t);
}
int register_task(void)
{
uint16_t sel;
sel = (CORE_ID+5) << 3;
asm volatile ("ltr %%ax" : : "a"(sel));
return 0;
return (size_t) kstacks[id] + KERNEL_STACK_SIZE - 16; // => stack is 16byte aligned
}
int arch_fork(task_t* task)
@ -229,14 +219,17 @@ static void gdt_set_gate(int num, unsigned long base, unsigned long limit,
*/
void gdt_install(void)
{
unsigned int i, mode;
unsigned int i;
unsigned long mode, limit;
memset(task_state_segments, 0x00, MAX_CORES*sizeof(tss_t));
#ifdef CONFIG_X86_32
mode = GDT_FLAG_32_BIT;
limit = 0xFFFFFFFF;
#elif defined(CONFIG_X86_64)
mode = GDT_FLAG_64_BIT;
limit = 0;
#else
#error invalid mode
#endif
@ -253,7 +246,7 @@ void gdt_install(void)
* is 0, the limit is 4 GByte, it uses 4KByte granularity,
* uses 32-bit opcodes, and is a Code Segment descriptor.
*/
gdt_set_gate(1, 0, 0xFFFFFFFF,
gdt_set_gate(1, 0, limit,
GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG | GDT_FLAG_PRESENT,
GDT_FLAG_4K_GRAN | mode);
@ -262,21 +255,21 @@ void gdt_install(void)
* same as our code segment, but the descriptor type in
* this entry's access byte says it's a Data Segment
*/
gdt_set_gate(2, 0, 0xFFFFFFFF,
gdt_set_gate(2, 0, limit,
GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG | GDT_FLAG_PRESENT,
GDT_FLAG_4K_GRAN | mode);
/*
* Create code segement for userspace applications (ring 3)
*/
gdt_set_gate(3, 0, 0xFFFFFFFF,
gdt_set_gate(3, 0, limit,
GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG | GDT_FLAG_PRESENT,
GDT_FLAG_4K_GRAN | mode);
/*
* Create data segement for userspace applications (ring 3)
*/
gdt_set_gate(4, 0, 0xFFFFFFFF,
gdt_set_gate(4, 0, limit,
GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG | GDT_FLAG_PRESENT,
GDT_FLAG_4K_GRAN | mode);
@ -289,12 +282,13 @@ void gdt_install(void)
task_state_segments[i].eflags = 0x1202;
task_state_segments[i].ss0 = 0x10; // data segment
task_state_segments[i].esp0 = 0xDEADBEEF; // invalid pseudo address
gdt_set_gate(5+i, (unsigned long) (task_state_segments+i), sizeof(tss_t)-1,
GDT_FLAG_PRESENT | GDT_FLAG_TSS | GDT_FLAG_RING0, mode);
#elif defined(CONFIG_X86_64)
task_state_segments[i].rsp0 = 0xDEADBEEF; // invalid pseudo address
gdt_set_gate(5+i*2, (unsigned long) (task_state_segments+i), sizeof(tss_t)-1,
GDT_FLAG_PRESENT | GDT_FLAG_TSS | GDT_FLAG_RING0, mode);
#endif
gdt_set_gate(5+i, (unsigned long) (task_state_segments+i), sizeof(tss_t)-1,
GDT_FLAG_PRESENT | GDT_FLAG_TSS | GDT_FLAG_RING0, 0);
}
/* Flush out the old GDT and install the new changes! */

View file

@ -39,7 +39,11 @@
* for which the 'presence' bit is cleared (0) will generate an
* "Unhandled Interrupt" exception
*/
#ifdef CONFIG_X86_64
static idt_entry_t idt[256] = {[0 ... 255] = {0, 0, 0, 0, 0, 0, 0}};
#else
static idt_entry_t idt[256] = {[0 ... 255] = {0, 0, 0, 0, 0}};
#endif
static idt_ptr_t idtp;
/*

View file

@ -35,7 +35,7 @@ static inline int isascii(int c)
/** Applies an and-operation to
* push the value of 'c' into the ASCII-range */
static inline int toascii(c)
static inline int toascii(int c)
{
return (((unsigned char)(c))&0x7f);
}