From: Fabrice Gautier <Fabrice_Gautier@sdesigns.com>
To: 'Nick Garnett' <nickg@cygnus.co.uk>, ecos-discuss@sourceware.cygnus.com
Subject: RE: [ECOS] Multi thread Debugging
Date: Thu, 31 Aug 2000 18:54:00 -0000 [thread overview]
Message-ID: <8AE4B526B977D411841F00A0CC334020052C3C@cuz-exchange.sdesigns.net> (raw)
Hi,
> -----Original Message-----
> From: Nick Garnett [ mailto:nickg@cygnus.co.uk ]
> Sent: Thursday, August 31, 2000 4:08 AM
> To: ecos-discuss@sourceware.cygnus.com
> Subject: Re: [ECOS] Multi thread Debugging
>
> All your observations are correct. The main problem is that thread
> saved contexts and interrupt saved contexts are different. In all
> other HALs they are the same. I suspect that the simplest fix for now
> is to change the format of the HAL_SavedRegisters structure to echo
> that pushed by "pusha" and replace the "movl"s in context.S with
> "pusha" and "popa".
I'm testing some changes like this. It seems to work with the HAL context.c
test, but with a more complicated program I've some strange crash I didn't
have before.
The program ends with an exception (SIGSEGV, SIGILL or SIGTRAP) and it seems
this is during a thread switch.
I suspect that in some cases the changes I've made may be unsafe. I'm not
sure if the switch context function have to be re-entrant it is safe to
assume that a context switch can't be interrupted by another context switch?
One main difference between my new version and the current version is that
the next context ptr is not saved as a part of the SavedRegisters structure.
So this pointer is pushed on the stack (as a parameter for
hal_thread_load_context) AFTER the current thread stack pointer has been
saved. So if another context switch occurs at this time I suppose the saved
context will be corrupted.
I post here the modifications I've made:
First the HAL_SavedRegisters structure:
=======================================
typedef struct
{
cyg_uint32 edi;
cyg_uint32 esi;
cyg_uint32 ebp;
cyg_uint32 esp;
cyg_uint32 ebx;
cyg_uint32 edx;
cyg_uint32 ecx;
cyg_uint32 eax;
cyg_uint32 vector; // if saved on interrupt contains intr vector
cyg_uint32 eip;
cyg_uint32 arg1; // cs (when intr) or parameter
cyg_uint32 arg2; // eflags (when intr) or parameter
} HAL_SavedRegisters;
*******************************************************
Then the context init routine:
==============================
//--------------------------------------------------------------------------
---
// Context Initialization
// Initialize the context of a thread.
// Arguments:
// _sp_ name of variable containing current sp, will be written with new sp
// _thread_ thread object address, passed as argument to entry point
// _entry_ entry point address.
// _id_ bit pattern used in initializing registers, for debugging.
#define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ ) \
CYG_MACRO_START \
register CYG_WORD* _sp_ = ((CYG_WORD*)((_sparg_) &~15)); \
register HAL_SavedRegisters *_regs_; \
\
/* The 'ret' executed at the end of hal_thread_load_context will */ \
/* use the last entry on the stack as a return pointer (_entry_). */ \
/* Cyg_HardwareThread::thread_entry expects one argument at stack */ \
/* offset 4 (_thread_). The (0xDEADBEEF) entry is the return addr */ \
/* for thread_entry (which is never used). */ \
*(--_sp_) = (CYG_WORD)(0); \
*(--_sp_) = (CYG_WORD)(0); \
*(--_sp_) = (CYG_WORD)(0); \
*(--_sp_) = (CYG_WORD)(0); \
\
_regs_ = (HAL_SavedRegisters *) \
((unsigned long)_sp_ - sizeof(HAL_SavedRegisters)); \
_regs_->arg2 = (CYG_WORD)(_thread_); \
_regs_->arg1 = (CYG_WORD)(0); \
_regs_->eip = (CYG_WORD)(_entry_); \
_regs_->vector = (CYG_WORD)(_id_); \
_sp_-=4; \
_regs_->esp = (CYG_WORD) _sp_; \
_regs_->ebp = (CYG_WORD)(_id_); \
_regs_->esi = (CYG_WORD)(_id_); \
_regs_->edi = (CYG_WORD)(_id_); \
_regs_->eax = (CYG_WORD)(_id_); \
_regs_->ebx = (CYG_WORD)(_id_); \
_regs_->ecx = (CYG_WORD)(_id_); \
_regs_->edx = (CYG_WORD)(_id_); \
(_sparg_) = (CYG_ADDRESS) _regs_; \
CYG_MACRO_END
*******************************************************
And the switch routine:
=======================
#---------------------------------------------------------------------------
---
# hal_thread_switch_context
# Switch thread contexts
# : 0(%esp) : return address
# : 4(%esp) : address of sp of next thread to execute
# : 8(%esp) : address of sp save location of current thread
#
# %eax, %ecx, and %edx are ours to abuse.
FUNC_START(hal_thread_switch_context)
# movl 4(%esp),%eax # next context ptr
# movl 8(%esp),%edx # this context ptr
popl %ebx # save return eip
popl %eax # get next context ptr
popl %edx # get this context ptr
# Save context
pushfl # save eflags
pushw %cs # save cs
pushw 0 # and pad to 32 bits
pushl %ebx # save eip
pushl $0xdeaddead # push vector
pusha # push general registers
# Save next context ptr in this context. Necessary because
# hal_thread_load_context expects to find the ptr on the stack,
# not in a register as on PPC.
# Store the context ptr
movl %esp,(%edx)
#push next context ptr as an argument to load context
pushl %eax
pushl $0xdeadbeef # load_context return pointer, never used
# Now fall through to hal_thread_load_context
#---------------------------------------------------------------------------
---
# hal_thread_load_context
# Load thread context
# : 4(%esp) (!= i386reg_next_context(%esp)) = address of sp of thread to
execute
# Note that this function is also the second half of
hal_thread_switch_context
# and is simply dropped into from it.
#
# %eax, %ecx, and %edx are ours to abuse.
FUNC_START(hal_thread_load_context)
#ifdef CYGHWR_HAL_I386_FPU
movl %cr0, %eax
orl $0x8, %eax
movl %eax, %cr0
#endif
movl 4(%esp),%eax # get new context ptr
movl (%eax),%esp
popal # unstack general registers
popl %ebx # unstack vector (should be 0xdeaddead)
ret
next reply other threads:[~2000-08-31 18:54 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-08-31 18:54 Fabrice Gautier [this message]
2000-09-01 3:12 ` Nick Garnett
-- strict thread matches above, loose matches on Subject: below --
2000-09-01 14:18 Fabrice Gautier
2000-08-31 15:31 Fabrice Gautier
2000-09-01 2:55 ` Nick Garnett
2000-08-31 3:56 Fabrice Gautier
2000-08-30 19:56 Fabrice Gautier
2000-08-31 4:15 ` Nick Garnett
2000-08-30 16:39 Fabrice Gautier
2000-08-25 12:06 Fabrice Gautier
2000-08-25 11:18 Fabrice Gautier
2000-08-25 11:38 ` Jonathan Larmour
2000-08-23 14:53 Fabrice Gautier
2000-08-24 7:17 ` Jonathan Larmour
2000-08-21 19:15 Fabrice Gautier
2000-08-15 12:00 Fabrice Gautier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8AE4B526B977D411841F00A0CC334020052C3C@cuz-exchange.sdesigns.net \
--to=fabrice_gautier@sdesigns.com \
--cc=ecos-discuss@sourceware.cygnus.com \
--cc=nickg@cygnus.co.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).