-#include "tss.h"
+#include "userprog/tss.h"
+#include <debug.h>
#include <stddef.h>
-#include "gdt.h"
-#include "lib/debug.h"
-#include "threads/mmu.h"
+#include "userprog/gdt.h"
+#include "threads/thread.h"
#include "threads/palloc.h"
+#include "threads/vaddr.h"
/* The Task-State Segment (TSS).
not in use, so we can always use that. Thus, when the
scheduler switches threads, it also changes the TSS's
stack pointer to point to the new thread's kernel stack.
- (The call is in schedule_tail() in thread.c.)
+ (The call is in thread_schedule_tail() in thread.c.)
- See [IA32-v3] 6.2.1 for a description of the TSS and 5.12.1
- for a description of when and how stack switching occurs
- during an interrupt. */
+ See [IA32-v3a] 6.2.1 "Task-State Segment (TSS)" for a
+ description of the TSS. See [IA32-v3a] 5.12.1 "Exception- or
+ Interrupt-Handler Procedures" for a description of when and
+ how stack switching occurs during an interrupt. */
struct tss
{
uint16_t back_link, :16;
/* 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 = palloc_get_page (PAL_ASSERT | PAL_ZERO);
tss->ss0 = SEL_KDSEG;
tss->bitmap = 0xdfff;
+ tss_update ();
}
/* Returns the kernel TSS. */
return tss;
}
-/* Sets the ring 0 stack pointer in the TSS to ESP0. */
+/* Sets the ring 0 stack pointer in the TSS to point to the end
+ of the thread stack. */
void
-tss_set_esp0 (uint8_t *esp0)
+tss_update (void)
{
ASSERT (tss != NULL);
- tss->esp0 = esp0;
+ tss->esp0 = (uint8_t *) thread_current () + PGSIZE;
}