fix: thread switch gets back into the isr routine but iret does not return to the correct frame
This commit is contained in:
@ -14,8 +14,8 @@ typedef enum {
|
|||||||
} state_t;
|
} state_t;
|
||||||
|
|
||||||
struct tcb {
|
struct tcb {
|
||||||
uint8_t *esp;
|
uint32_t *esp;
|
||||||
uint8_t *esp0;
|
uint32_t *esp0;
|
||||||
uint16_t tid;
|
uint16_t tid;
|
||||||
state_t state;
|
state_t state;
|
||||||
struct pcb *process;
|
struct pcb *process;
|
||||||
|
|||||||
@ -48,5 +48,6 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic)
|
|||||||
create_process(1);
|
create_process(1);
|
||||||
create_thread(current_pcb, shell_init);
|
create_thread(current_pcb, shell_init);
|
||||||
toris();
|
toris();
|
||||||
while (true);
|
while (true)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,11 +4,9 @@
|
|||||||
.global switch_thread
|
.global switch_thread
|
||||||
|
|
||||||
switch_thread:
|
switch_thread:
|
||||||
push ebx
|
mov edx, DWORD PTR [esp]
|
||||||
push ebp
|
cmp DWORD PTR [current_tcb], 0
|
||||||
push edi
|
je .LABEL1
|
||||||
push esi
|
|
||||||
|
|
||||||
mov eax, [current_tcb]
|
mov eax, [current_tcb]
|
||||||
|
|
||||||
// save the current stack pointer to the old stack
|
// save the current stack pointer to the old stack
|
||||||
@ -16,6 +14,7 @@ switch_thread:
|
|||||||
|
|
||||||
// stack pointer + the 4 regs pushed
|
// stack pointer + the 4 regs pushed
|
||||||
// and + 1 to get the argument (next thread)
|
// and + 1 to get the argument (next thread)
|
||||||
|
.LABEL1:
|
||||||
mov esi, [esp+(4+1)*4]
|
mov esi, [esp+(4+1)*4]
|
||||||
mov [current_tcb], esi
|
mov [current_tcb], esi
|
||||||
|
|
||||||
@ -23,9 +22,6 @@ switch_thread:
|
|||||||
|
|
||||||
mov esp, [eax+0] // get esp
|
mov esp, [eax+0] // get esp
|
||||||
|
|
||||||
pop esi
|
push edx
|
||||||
pop edi
|
|
||||||
pop ebp
|
|
||||||
pop ebx
|
|
||||||
|
|
||||||
iret
|
ret
|
||||||
|
|||||||
@ -22,19 +22,18 @@ struct tcb *create_thread(struct pcb *process, void (*routine)(void))
|
|||||||
// set esp to "skip" the 4 GPRs and eip later to be used as the context
|
// set esp to "skip" the 4 GPRs and eip later to be used as the context
|
||||||
// of the thread
|
// of the thread
|
||||||
new_tcb->esp = new_tcb->esp0 + STACK_SIZE - 5 * 4;
|
new_tcb->esp = new_tcb->esp0 + STACK_SIZE - 5 * 4;
|
||||||
memcpy(new_tcb->esp + 4, routine, 4);
|
new_tcb->esp[4] = (uint32_t)routine;
|
||||||
new_tcb->process = process;
|
new_tcb->process = process;
|
||||||
new_tcb->next = NULL;
|
new_tcb->next = NULL;
|
||||||
new_tcb->state = NEW;
|
new_tcb->state = NEW;
|
||||||
|
|
||||||
struct tcb *it = process->thread_list;
|
if (process->thread_list == NULL) {
|
||||||
if (it) {
|
|
||||||
while (it)
|
|
||||||
it = it->next;
|
|
||||||
it = new_tcb;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
process->thread_list = new_tcb;
|
process->thread_list = new_tcb;
|
||||||
|
} else {
|
||||||
|
struct tcb *it = process->thread_list;
|
||||||
|
while (it->next)
|
||||||
|
it = it->next;
|
||||||
|
it->next = new_tcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_tcb;
|
return new_tcb;
|
||||||
|
|||||||
Reference in New Issue
Block a user