1 |
/* ??? thread/port. |
/* ??? thread/port. |
2 |
Copyright 1999, 2000, 2001 Johan Rydberg, jrydberg@opencores.org. |
Copyright 1999, 2000, 2001, 2002 Johan Rydberg, jrydberg@opencores.org. |
3 |
|
|
4 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
5 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
110 |
ktss [CPU_CURRENT ()].esp0 = stack_top; |
ktss [CPU_CURRENT ()].esp0 = stack_top; |
111 |
ktss [CPU_CURRENT ()].ss0 = KERNEL_DS; |
ktss [CPU_CURRENT ()].ss0 = KERNEL_DS; |
112 |
|
|
113 |
/* Use system LDT. */ |
/* Check if we should use per-pcb LDT. */ |
114 |
|
if (pcb->ldt_p) |
115 |
|
{ |
116 |
|
int ldt_seg; |
117 |
|
|
118 |
|
ldt_seg = KERNEL_TSS + (0x8 * (CPU_CURRENT () * 2 + 1)); |
119 |
|
|
120 |
load_ldt (KERNEL_LDT); |
gdt [ldt_seg / 8] = pcb->gdt_entry; |
121 |
|
load_ldt (ldt_seg); |
122 |
|
} |
123 |
|
else |
124 |
|
/* Use system LDT. */ |
125 |
|
load_ldt (KERNEL_LDT); |
126 |
} |
} |
127 |
|
|
128 |
/* Switch to the first thread on a CPU. */ |
/* Switch to the first thread on a CPU. */ |
162 |
PROCESSOR_CURRENT()->current_thread = new_thread; |
PROCESSOR_CURRENT()->current_thread = new_thread; |
163 |
new_thread->last_processor = PROCESSOR_CURRENT(); |
new_thread->last_processor = PROCESSOR_CURRENT(); |
164 |
|
|
165 |
|
/* Point top of kernel stack to user`s registers. */ |
166 |
|
STACK_IEL(new_thread->kernel_stack)->saved_state |
167 |
|
= & new_thread->pcb.trap_frame; |
168 |
|
|
169 |
/* Load the rest of the user state for the new thread. */ |
/* Load the rest of the user state for the new thread. */ |
170 |
switch_ktss (&new_thread->pcb); |
switch_ktss (&new_thread->pcb); |
171 |
return cpu_switch_context (old_thread, continuation, new_thread); |
return cpu_switch_context (old_thread, continuation, new_thread); |
220 |
thread_set_status (struct thread *thread, thread_status_flavor_t flavor, |
thread_set_status (struct thread *thread, thread_status_flavor_t flavor, |
221 |
thread_status_t status, int count) |
thread_status_t status, int count) |
222 |
{ |
{ |
223 |
|
kern_return_t kr; |
224 |
|
|
225 |
switch (flavor) |
switch (flavor) |
226 |
{ |
{ |
227 |
case THREAD_STATUS_FLAVOR_CPU_STATE: |
case THREAD_STATUS_FLAVOR_CPU_STATE: |
229 |
sizeof (struct thread_state_i386)); |
sizeof (struct thread_state_i386)); |
230 |
return KERN_SUCCESS; |
return KERN_SUCCESS; |
231 |
|
|
232 |
|
case THREAD_STATE_FLAVOR_I386_LDT: |
233 |
|
{ |
234 |
|
struct thread_state_i386_ldt *ldt_state |
235 |
|
= (struct thread_state_i386_ldt *) status; |
236 |
|
|
237 |
|
kr = initialize_user_segment (&thread->pcb, |
238 |
|
ldt_state); |
239 |
|
if (kr == KERN_SUCCESS) |
240 |
|
{ |
241 |
|
thread->pcb.ldt_p = 1; |
242 |
|
if (thread == THREAD_CURRENT ()) |
243 |
|
switch_ktss (&thread->pcb); |
244 |
|
} |
245 |
|
|
246 |
|
return kr; |
247 |
|
} |
248 |
|
|
249 |
default: |
default: |
250 |
panic ("invalid thread status?"); |
panic ("invalid thread status?"); |
251 |
} |
} |