[syslinux:lwip] thread: thread-switch the real-mode stack, too
syslinux-bot for H. Peter Anvin
hpa at zytor.com
Fri Apr 22 20:06:22 PDT 2011
Commit-ID: f5203bfa11fde88d16f471b4050ed1da73387c7a
Gitweb: http://syslinux.zytor.com/commit/f5203bfa11fde88d16f471b4050ed1da73387c7a
Author: H. Peter Anvin <hpa at zytor.com>
AuthorDate: Thu, 21 Apr 2011 22:16:14 -0700
Committer: H. Peter Anvin <hpa at zytor.com>
CommitDate: Thu, 21 Apr 2011 22:16:14 -0700
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 at zytor.com>
---
core/include/thread.h | 1 +
core/pm.inc | 1 +
core/thread/exit_thread.c | 7 +++++++
core/thread/start_thread.c | 19 ++++++++++++++++---
core/thread/thread_asm.S | 2 ++
5 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/core/include/thread.h b/core/include/thread.h
index 704962e..b283424 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 8690cab..ddeca25 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 0aadfb6..444f9e2 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 52cc7df..77dc0ea 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 34843a5..ec3e0ad 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
More information about the Syslinux-commits
mailing list