metalsvm/arch/x86/kernel/schedule.asm
stefan 71188c92f9 - complete restart of the project
- support of TSS-based task switching
- add a mailbox template
- suport of user level task
- support of system calls


git-svn-id: http://svn.lfbs.rwth-aachen.de/svn/scc/trunk/MetalSVM@47 315a16e6-25f9-4109-90ae-ca3045a26c18
2010-08-09 11:47:51 +00:00

147 lines
2.9 KiB
NASM

;
; Copyright 2010 Stefan Lankes, Chair for Operating Systems,
; RWTH Aachen University
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; This file is part of metalsvm.
[BITS 32]
SECTION .code
extern get_new_task
extern current_task
;extern task_table
; C prototyp:
;
; typedef struct {
; unsigned char* top;
; unsigned int ip;
; tid_t id;
; ...
; } task_t;
; After an interrupt, the original return address has to push on the stack
; because we want to comeback...
global schedule_entry
schedule_entry:
cli
sub esp, 4 ; add some space for the retunr address,
; which is stored in current_task->ip
pushfd
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
;mov eax, DWORD [current_id]
;shl eax, 0x4 ; 16 = sizeof(task_t)
;mov edx, DWORD [eax+task_table+4]
;mov [esp+13*4], edx
;mov DWORD [eax+task_table+4], 0
mov eax, DWORD [current_task]
mov edx, [eax+4]
mov DWORD [esp+13*4], edx
mov DWORD [eax+4], 0x00
jmp L1
; Scheduler, which switchs to the new tasks
global schedule
schedule:
ret
cli
; return address is already on the stack (via call schedule)
pop eax
pushfd
push 0x08
push eax
push byte 0
push byte 32
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, DWORD [current_task]
mov [eax], esp
;call get_new_task
mov DWORD [current_task], eax
mov esp, [eax]
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
xor eax, eax ; return value is 0
iret
cli
pushfd
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; store current esp
;mov eax, DWORD [current_id]
;shl eax, 0x4 ; 16 = sizeof(task_t)
L1:
;mov [eax+task_table], esp
mov eax, DWORD [current_task]
mov [eax], esp
;call get_new_task
; set current task and restore esp
;mov DWORD [current_id], eax
;shl eax, 0x4 ; 16 = sizeof(task_t)
;mov esp, [eax+task_table]
mov DWORD [current_task], eax
mov esp, [eax]
pop gs
pop fs
pop es
pop ds
popa
popfd
sti
ret