From: Ben Pfaff Date: Wed, 1 Sep 2004 22:25:56 +0000 (+0000) Subject: Break TSS out of GDT. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=commitdiff_plain;h=a051c001c942a1f9cce57b1beec79794f9c7089f Break TSS out of GDT. --- diff --git a/src/Makefile.inc b/src/Makefile.inc index d6b9519..c125eba 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -18,6 +18,7 @@ ASFLAGS = -Wa,--gstabs+ $(INCLUDES) $(DEFINES) THREADS_SRC = start.S # Must be linked first. THREADS_SRC += init.c # Main program. THREADS_SRC += gdt.c # GDT initialization. +THREADS_SRC += tss.c # TSS management. THREADS_SRC += thread.c # Thread management core. THREADS_SRC += switch.S # Thread switch routine. THREADS_SRC += interrupt.c # Interrupt core. diff --git a/src/threads/gdt.c b/src/threads/gdt.c index 2fd6948..6348f5d 100644 --- a/src/threads/gdt.c +++ b/src/threads/gdt.c @@ -2,6 +2,7 @@ #include "debug.h" #include "mmu.h" #include "palloc.h" +#include "tss.h" /* System segment or code/data segment? */ enum seg_class @@ -87,8 +88,6 @@ make_tss_desc (void *laddr) static uint64_t gdt[SEL_CNT]; -struct tss *tss; - /* Sets up a proper GDT. The bootstrap loader's GDT didn't include user-mode selectors or a TSS. */ void @@ -96,21 +95,13 @@ gdt_init (void) { uint64_t gdtr_operand; - /* Our TSS is never used in a call gate or task gate, so only a - few fields of it are ever referenced, and those are the only - ones we initialize. */ - tss = palloc_get (PAL_ASSERT | PAL_ZERO); - tss->esp0 = (uint32_t) ptov(0x20000); - tss->ss0 = SEL_KDSEG; - tss->bitmap = 0xdfff; - /* Initialize GDT. */ gdt[SEL_NULL / sizeof *gdt] = 0; gdt[SEL_KCSEG / sizeof *gdt] = make_code_desc (0); gdt[SEL_KDSEG / sizeof *gdt] = make_data_desc (0); gdt[SEL_UCSEG / sizeof *gdt] = make_code_desc (3); gdt[SEL_UDSEG / sizeof *gdt] = make_data_desc (3); - gdt[SEL_TSS / sizeof *gdt] = make_tss_desc (tss); + gdt[SEL_TSS / sizeof *gdt] = make_tss_desc (tss_get ()); /* Load GDTR, TR. */ gdtr_operand = make_dtr_operand (sizeof gdt - 1, gdt); diff --git a/src/threads/gdt.h b/src/threads/gdt.h index 68507bc..c32ceab 100644 --- a/src/threads/gdt.h +++ b/src/threads/gdt.h @@ -13,39 +13,12 @@ #ifndef __ASSEMBLER__ #include -struct tss - { - uint16_t back_link, :16; - uint32_t esp0; - uint16_t ss0, :16; - uint32_t esp1; - uint16_t ss1, :16; - uint32_t esp2; - uint16_t ss2, :16; - uint32_t cr3; - uint32_t eip; - uint32_t eflags; - uint32_t eax, ecx, edx, ebx; - uint32_t esp, ebp, esi, edi; - uint16_t es, :16; - uint16_t cs, :16; - uint16_t ss, :16; - uint16_t ds, :16; - uint16_t fs, :16; - uint16_t gs, :16; - uint16_t ldt, :16; - uint16_t trace, bitmap; - }; - - static inline uint64_t make_dtr_operand (uint16_t limit, void *base) { return limit | ((uint64_t) (uint32_t) base << 16); } -extern struct tss *tss; - void gdt_init (void); #endif diff --git a/src/threads/init.c b/src/threads/init.c index b70c16c..a3ab43d 100644 --- a/src/threads/init.c +++ b/src/threads/init.c @@ -17,6 +17,7 @@ #include "serial.h" #include "thread.h" #include "timer.h" +#include "tss.h" #include "vga.h" #ifdef FILESYS #include "filesys.h" @@ -74,6 +75,7 @@ main (void) /* Initialize memory system. */ palloc_init (); paging_init (); + tss_init (); gdt_init (); malloc_init (); diff --git a/src/threads/tss.c b/src/threads/tss.c new file mode 100644 index 0000000..37d075b --- /dev/null +++ b/src/threads/tss.c @@ -0,0 +1,58 @@ +#include "tss.h" +#include +#include "debug.h" +#include "gdt.h" +#include "mmu.h" +#include "palloc.h" + +struct tss + { + uint16_t back_link, :16; + void *esp0; + uint16_t ss0, :16; + void *esp1; + uint16_t ss1, :16; + void *esp2; + uint16_t ss2, :16; + uint32_t cr3; + void (*eip) (void); + uint32_t eflags; + uint32_t eax, ecx, edx, ebx; + uint32_t esp, ebp, esi, edi; + uint16_t es, :16; + uint16_t cs, :16; + uint16_t ss, :16; + uint16_t ds, :16; + uint16_t fs, :16; + uint16_t gs, :16; + uint16_t ldt, :16; + uint16_t trace, bitmap; + }; + +static struct tss *tss; + +void +tss_init (void) +{ + /* Our TSS is never used in a call gate or task gate, so only a + few fields of it are ever referenced, and those are the only + ones we initialize. */ + tss = palloc_get (PAL_ASSERT | PAL_ZERO); + tss->esp0 = ptov(0x20000); + tss->ss0 = SEL_KDSEG; + tss->bitmap = 0xdfff; +} + +struct tss * +tss_get (void) +{ + ASSERT (tss != NULL); + return tss; +} + +void +tss_set_esp0 (uint8_t *esp0) +{ + ASSERT (tss != NULL); + tss->esp0 = esp0; +} diff --git a/src/threads/tss.h b/src/threads/tss.h new file mode 100644 index 0000000..a5476c7 --- /dev/null +++ b/src/threads/tss.h @@ -0,0 +1,11 @@ +#ifndef HEADER_TSS_H +#define HEADER_TSS_H + +#include + +struct tss; +void tss_init (void); +struct tss *tss_get (void); +void tss_set_esp0 (uint8_t *); + +#endif /* tss.h */ diff --git a/src/userprog/addrspace.c b/src/userprog/addrspace.c index 519da93..1170f16 100644 --- a/src/userprog/addrspace.c +++ b/src/userprog/addrspace.c @@ -3,13 +3,13 @@ #include "debug.h" #include "file.h" #include "filesys.h" -#include "gdt.h" #include "init.h" #include "lib.h" #include "mmu.h" #include "paging.h" #include "palloc.h" #include "thread.h" +#include "tss.h" /* We load ELF binaries. The following definitions are taken from the ELF specification more-or-less verbatim. */ @@ -275,5 +275,5 @@ addrspace_activate (struct thread *t) if (t->pagedir != NULL) pagedir_activate (t->pagedir); - tss->esp0 = (uint32_t) t + PGSIZE; + tss_set_esp0 ((uint8_t *) t + PGSIZE); }