during the context switch, we have to update esp0 in TSS
This commit is contained in:
parent
aed7b1ce8d
commit
b3fb07c4f6
2 changed files with 17 additions and 4 deletions
|
@ -199,6 +199,7 @@ isrstub_pseudo_error 9
|
||||||
extern irq_handler
|
extern irq_handler
|
||||||
extern get_current_stack
|
extern get_current_stack
|
||||||
extern finish_task_switch
|
extern finish_task_switch
|
||||||
|
extern set_kernel_stack
|
||||||
|
|
||||||
global switch_context
|
global switch_context
|
||||||
ALIGN 4
|
ALIGN 4
|
||||||
|
@ -249,6 +250,9 @@ common_switch:
|
||||||
or eax, 8
|
or eax, 8
|
||||||
mov cr0, eax
|
mov cr0, eax
|
||||||
|
|
||||||
|
; set esp0 in the task state segment
|
||||||
|
call set_kernel_stack
|
||||||
|
|
||||||
; call cleanup code
|
; call cleanup code
|
||||||
call finish_task_switch
|
call finish_task_switch
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <asm/gdt.h>
|
#include <asm/gdt.h>
|
||||||
#include <asm/tss.h>
|
#include <asm/tss.h>
|
||||||
|
|
||||||
gdt_ptr_t gp;
|
gdt_ptr_t gp;
|
||||||
static tss_t task_state_segment __attribute__ ((aligned (PAGE_SIZE)));
|
static tss_t task_state_segment __attribute__ ((aligned (PAGE_SIZE)));
|
||||||
// currently, our kernel has full access to the ioports
|
// 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}};
|
static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0}};
|
||||||
|
@ -46,6 +46,13 @@ static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0,
|
||||||
*/
|
*/
|
||||||
extern void gdt_flush(void);
|
extern void gdt_flush(void);
|
||||||
|
|
||||||
|
void set_kernel_stack(void)
|
||||||
|
{
|
||||||
|
task_t* curr_task = current_task;
|
||||||
|
|
||||||
|
task_state_segment.esp0 = (size_t) curr_task->stack + KERNEL_STACK_SIZE-16;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup a descriptor in the Global Descriptor Table */
|
/* Setup a descriptor in the Global Descriptor Table */
|
||||||
void gdt_set_gate(int num, unsigned long base, unsigned long limit,
|
void gdt_set_gate(int num, unsigned long base, unsigned long limit,
|
||||||
unsigned char access, unsigned char gran)
|
unsigned char access, unsigned char gran)
|
||||||
|
@ -122,13 +129,15 @@ void gdt_install(void)
|
||||||
* Create data segement for userspace applications (ring 3)
|
* Create data segement for userspace applications (ring 3)
|
||||||
*/
|
*/
|
||||||
gdt_set_gate(4, 0, limit,
|
gdt_set_gate(4, 0, limit,
|
||||||
GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG | GDT_FLAG_PRESENT,
|
GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG | GDT_FLAG_PRESENT,
|
||||||
GDT_FLAG_4K_GRAN | mode);
|
GDT_FLAG_4K_GRAN | mode);
|
||||||
|
|
||||||
/* set default values */
|
/* set default values */
|
||||||
task_state_segment.eflags = 0x1202;
|
task_state_segment.eflags = 0x1202;
|
||||||
task_state_segment.ss0 = 0x10; // data segment
|
task_state_segment.ss0 = 0x10; // data segment
|
||||||
task_state_segment.esp0 = 0xDEADBEEF; // invalid pseudo address
|
task_state_segment.esp0 = 0xDEADBEEF; // invalid pseudo address
|
||||||
|
task_state_segment.cs = 0x0b;
|
||||||
|
task_state_segment.ss = task_state_segment.ds = task_state_segment.es = task_state_segment.fs = task_state_segment.gs = 0x13;
|
||||||
gdt_set_gate(5, (unsigned long) (&task_state_segment), sizeof(tss_t)-1,
|
gdt_set_gate(5, (unsigned long) (&task_state_segment), sizeof(tss_t)-1,
|
||||||
GDT_FLAG_PRESENT | GDT_FLAG_TSS | GDT_FLAG_RING0, mode);
|
GDT_FLAG_PRESENT | GDT_FLAG_TSS | GDT_FLAG_RING0, mode);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue