aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-04-21 22:16:14 -0700
committerH. Peter Anvin <hpa@zytor.com>2011-04-21 22:16:14 -0700
commitf5203bfa11fde88d16f471b4050ed1da73387c7a (patch)
tree1240d92a993cf49fe1b92ad3d564596009b45794 /core
parent3f6823a63c7f153421bbca343423a5fddc1a4ec1 (diff)
downloadsyslinux-f5203bfa11fde88d16f471b4050ed1da73387c7a.tar.gz
syslinux-f5203bfa11fde88d16f471b4050ed1da73387c7a.tar.xz
syslinux-f5203bfa11fde88d16f471b4050ed1da73387c7a.zip
thread: thread-switch the real-mode stack, too
When this code was originally written, we didn't have lmalloc(). Now when lmalloc() is implemented, let each real-mode task have its own stack. Note that this means we absolutely have to continue to support the SS != CS, DS model in the real-mode code, which should already be the case, but... Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'core')
-rw-r--r--core/include/thread.h1
-rw-r--r--core/pm.inc1
-rw-r--r--core/thread/exit_thread.c7
-rw-r--r--core/thread/start_thread.c19
-rw-r--r--core/thread/thread_asm.S2
5 files changed, 27 insertions, 3 deletions
diff --git a/core/include/thread.h b/core/include/thread.h
index 704962e1..b283424d 100644
--- a/core/include/thread.h
+++ b/core/include/thread.h
@@ -26,6 +26,7 @@ struct thread {
const char *name; /* Name (for debugging) */
struct thread_list list;
struct thread_block *blocked;
+ void *stack, *rmstack; /* Stacks, iff allocated by malloc/lmalloc */
void *pvt; /* For the benefit of lwIP */
int prio;
};
diff --git a/core/pm.inc b/core/pm.inc
index 8690cabe..ddeca25c 100644
--- a/core/pm.inc
+++ b/core/pm.inc
@@ -459,6 +459,7 @@ pm_init:
section .earlybss
alignb 8
IDT: resq 256
+ global RealModeSSSP
RealModeSSSP resd 1 ; Real-mode SS:SP
section .gentextnr ; Autogenerated 32-bit code
diff --git a/core/thread/exit_thread.c b/core/thread/exit_thread.c
index 0aadfb6c..444f9e27 100644
--- a/core/thread/exit_thread.c
+++ b/core/thread/exit_thread.c
@@ -1,5 +1,6 @@
#include "thread.h"
#include <limits.h>
+#include <stdlib.h>
#include <klibc/compiler.h>
__noreturn __exit_thread(void)
@@ -13,6 +14,12 @@ __noreturn __exit_thread(void)
curr->list.prev->next = curr->list.next;
curr->list.next->prev = curr->list.prev;
+ /* Free allocated stacks */
+ if (curr->stack)
+ free(curr->stack);
+ if (curr->rmstack)
+ free(curr->stack);
+
/*
* Note: __schedule() can explictly handle the case where
* curr isn't part of the linked list anymore, as long as
diff --git a/core/thread/start_thread.c b/core/thread/start_thread.c
index 52cc7dfb..77dc0ea8 100644
--- a/core/thread/start_thread.c
+++ b/core/thread/start_thread.c
@@ -1,7 +1,11 @@
#include <string.h>
#include <stdlib.h>
+#include <com32.h>
+#include "core.h"
#include "thread.h"
+#define REAL_MODE_STACK_SIZE 4096
+
extern void __start_thread(void);
/*
@@ -9,6 +13,7 @@ extern void __start_thread(void);
*/
struct thread_stack {
int errno;
+ uint16_t rmsp, rmss;
uint32_t edi, esi, ebp, ebx;
void (*eip)(void);
};
@@ -18,7 +23,7 @@ struct thread *start_thread(const char *name, size_t stack_size, int prio,
{
irq_state_t irq;
struct thread *curr, *t;
- char *stack;
+ char *stack, *rmstack;
const size_t thread_mask = 31; /* Alignment mask */
struct thread_stack *sp;
@@ -26,17 +31,25 @@ struct thread *start_thread(const char *name, size_t stack_size, int prio,
stack = malloc(stack_size + sizeof(struct thread));
if (!stack)
return NULL;
+ rmstack = lmalloc(REAL_MODE_STACK_SIZE);
+ if (!rmstack) {
+ free(stack);
+ return NULL;
+ }
t = (struct thread *)stack;
- stack += sizeof(struct thread);
-
memset(t, 0, sizeof *t);
+ t->stack = stack;
+ t->rmstack = rmstack;
+ stack += sizeof(struct thread);
/* sp allocated from the end of the stack */
sp = (struct thread_stack *)(stack + stack_size) - 1;
t->esp = sp;
sp->errno = 0;
+ sp->rmss = SEG(rmstack);
+ sp->rmsp = OFFS_WRT(rmstack + REAL_MODE_STACK_SIZE, sp->rmss);
sp->esi = (size_t)start_func;
sp->edi = (size_t)func_arg;
sp->ebx = irq_state(); /* Inherit the IRQ state from the spawner */
diff --git a/core/thread/thread_asm.S b/core/thread/thread_asm.S
index 34843a51..ec3e0add 100644
--- a/core/thread/thread_asm.S
+++ b/core/thread/thread_asm.S
@@ -6,12 +6,14 @@ __switch_to:
pushl %ebp
pushl %esi
pushl %edi
+ pushl RealModeSSSP
pushl errno /* Hack! */
movl %esp, (%edx)
movl %eax, __current
movl (%eax), %esp
popl errno
+ popl RealModeSSSP
popl %edi
popl %esi
popl %ebp