blob: f2c2f84eda1a118543e734b4892413be0a40a10d [file] [log] [blame]
Corey Tabaka84697242009-03-26 02:32:01 -04001/*
2 * Copyright (c) 2009 Corey Tabaka
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <sys/types.h>
24#include <string.h>
25#include <stdlib.h>
26#include <debug.h>
27#include <kernel/thread.h>
28#include <arch/x86.h>
29#include <arch/x86/descriptor.h>
30
31/*struct context_switch_frame {
32 uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
33 uint32_t ds, es, fs, gs;
34 uint32_t eip, cs, eflags;
35};*/
36struct context_switch_frame {
37 uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
38 uint32_t eflags;
39 uint32_t eip;
40};
41
42extern void x86_context_switch(addr_t *old_sp, addr_t new_sp);
43
44static void initial_thread_func(void) __NO_RETURN;
45static void initial_thread_func(void)
46{
47 int ret;
48
49// dprintf("initial_thread_func: thread %p calling %p with arg %p\n", current_thread, current_thread->entry, current_thread->arg);
50// dump_thread(current_thread);
51
52 /* exit the implicit critical section we're within */
53 exit_critical_section();
54
55 ret = current_thread->entry(current_thread->arg);
56
57// dprintf("initial_thread_func: thread %p exiting with %d\n", current_thread, ret);
58
59 thread_exit(ret);
60}
61
62void arch_thread_initialize(thread_t *t)
63{
64 // create a default stack frame on the stack
65 vaddr_t stack_top = (vaddr_t)t->stack + t->stack_size;
66
67 // make sure the top of the stack is 8 byte aligned for EABI compliance
68 stack_top = ROUNDDOWN(stack_top, 8);
69
70 struct context_switch_frame *frame = (struct context_switch_frame *)(stack_top);
71 frame--;
72
73 // fill it in
74 memset(frame, 0, sizeof(*frame));
75
76 frame->eip = (vaddr_t) &initial_thread_func;
77 frame->eflags = 0x3002; // IF = 0, NT = 0, IOPL = 3
78 //frame->cs = CODE_SELECTOR;
79 //frame->fs = DATA_SELECTOR;
80 //frame->gs = DATA_SELECTOR;
81 //frame->es = DATA_SELECTOR;
82 //frame->ds = DATA_SELECTOR;
83
84 // set the stack pointer
85 t->arch.esp = (vaddr_t)frame;
86}
87
88void arch_context_switch(thread_t *oldthread, thread_t *newthread)
89{
90 //dprintf(DEBUG, "arch_context_switch: old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name);
91
92 __asm__ __volatile__ (
93 "pushl $1f \n\t"
94 "pushf \n\t"
95 "pusha \n\t"
96 "movl %%esp,(%%edx) \n\t"
97 "movl %%eax,%%esp \n\t"
98 "popa \n\t"
99 "popf \n\t"
100 "ret \n\t"
101 "1: \n\t"
102
103 :
104 : "d" (&oldthread->arch.esp), "a" (newthread->arch.esp)
105 );
106
107 /*__asm__ __volatile__ (
108 "pushf \n\t"
109 "pushl %%cs \n\t"
110 "pushl $1f \n\t"
111 "pushl %%gs \n\t"
112 "pushl %%fs \n\t"
113 "pushl %%es \n\t"
114 "pushl %%ds \n\t"
115 "pusha \n\t"
116 "movl %%esp,(%%edx) \n\t"
117 "movl %%eax,%%esp \n\t"
118 "popa \n\t"
119 "popl %%ds \n\t"
120 "popl %%es \n\t"
121 "popl %%fs \n\t"
122 "popl %%gs \n\t"
123 "iret \n\t"
124 "1: "
125 :
126 : "d" (&oldthread->arch.esp), "a" (newthread->arch.esp)
127 );*/
128}
129