[OpenBIOS] r547 - in cpu/x86: . Linux

svn at openbios.org svn at openbios.org
Wed Aug 15 22:20:01 CEST 2007


Author: wmb
Date: 2007-08-15 22:20:01 +0200 (Wed, 15 Aug 2007)
New Revision: 547

Added:
   cpu/x86/Linux/catchexc.fth
Modified:
   cpu/x86/loadmach.fth
Log:
Added signal handling to the x86 Linux-hosted Forth.









Added: cpu/x86/Linux/catchexc.fth
===================================================================
--- cpu/x86/Linux/catchexc.fth	                        (rev 0)
+++ cpu/x86/Linux/catchexc.fth	2007-08-15 20:20:01 UTC (rev 547)
@@ -0,0 +1,229 @@
+\ See license at end of file
+
+decimal
+
+only forth also hidden also  forth definitions
+: enterforth
+   handle-breakpoint
+;
+
+label reenter
+   \ We get here from then end of save-state, either by branching directly
+   \ or by modifying the return address in the DPMI exception frame.
+
+   make-odd 			 	\ word-align address
+   'body main-task   dup #  dx  mov
+   -4 allot  token, 			\ rewrite address as relocatable
+
+   0 [dx]             up  mov		\ Establish user pointer
+
+   \ Establish the Data and Return stacks
+   'user rp0          rp   mov
+   'user sp0          bx   mov
+
+   \ Restart the Forth interpreter.
+   cld
+
+   \ Execute enterforth
+\   'body enterforth #)  ip  lea
+   make-even 				\ word-align for relocation
+   'body enterforth  dup #)  ip  lea
+   -4 allot  token, 			\ rewrite address as relocatable   
+c;
+
+\ This is the signal handler.  When it is called, the stack contains:
+\
+\   struct sigcontext  ( See /usr/include/asm/sigcontext.h )
+\   signal number
+\   return address
+\
+\ We copy the data from sigcontext and fiddle the EIP value in sigcontext
+\ so that Forth is re-entered at the enterforth addresss
+
+\ For reference, sigcontext contains:
+\   gs, fs, es, ds                           00..0c
+\   edi, esi, ebp, esp, ebx, edx, ecx, eax   10..2c
+\   trapno, err, eip, cs                     30..3c
+\   esp_at_signal, ss, *fpstate, oldmask     40..4c
+\   cr2                                      50
+
+label save-state-signal
+
+   make-odd 			 	\ word-align address
+   'body main-task   dup #  dx  mov
+   -4 allot  token, 			\ rewrite address as relocatable
+
+   0 [dx]             up  mov		\ Establish user pointer
+   'user cpu-state    bx  mov		\ Base address of save area
+
+   4 [sp]             si  lea           \ Address of signal#
+
+   cld         \ Increment pointers
+   ax lods  ax  offset-of int# [bx]  mov
+
+   ax lods  ax  offset-of %gs  [bx]  mov
+   ax lods  ax  offset-of %fs  [bx]  mov
+   ax lods  ax  offset-of %es  [bx]  mov
+   ax lods  ax  offset-of %ds  [bx]  mov
+
+   ax lods  ax  offset-of %edi [bx]  mov
+   ax lods  ax  offset-of %esi [bx]  mov
+   ax lods  ax  offset-of %ebp [bx]  mov
+   ax lods  ax  offset-of %esp [bx]  mov		\ Correct ESP value will be set later
+   ax lods  ax  offset-of %ebx [bx]  mov
+   ax lods  ax  offset-of %edx [bx]  mov
+   ax lods  ax  offset-of %ecx [bx]  mov
+   ax lods  ax  offset-of %eax [bx]  mov
+
+   ax lods                                  \ Skip trapno
+   ax lods  ax  offset-of %error [bx]  mov  \ Save err
+
+   ax lods  ax  offset-of %eip [bx]  mov
+
+   \ Change the resume address to go to "reenter"
+   make-odd 			 	\ word-align address
+   'body reenter   dup #  ax mov
+   -4 allot  token, 			\ rewrite address as relocatable
+   ax  -4 [si]  mov                     \ Resume at reenter address
+
+   ax lods  ax  offset-of %cs      [bx]  mov
+   ax lods  ax  offset-of %eflags  [bx]  mov
+   ax lods                                    \ Skip esp_at_signal
+   ax lods  ax  offset-of %ss      [bx]  mov
+
+   ax ax xor      ax dec
+   ax offset-of %state-valid [bx]  mov	\ mark saved state as valid
+
+   \ Copy the entire Forth data stack and return stack areas to a save area.
+   up dx mov    \ Save UP
+
+   \ Data Stack  (load si first because di is the user pointer!)
+   'user sp0          si   mov
+   'user pssave       di   mov    \ Address of data stack save area
+   ps-size #          si   sub    \ Bottom of data stack area (in longwords)
+
+   ps-size 4 / #      cx   mov    \ Size of data stack area
+   rep  movs
+
+   dx up mov    \ Get user pointer back
+
+   \ Return Stack  (load si first because di is the user pointer!)
+   'user rp0          si   mov
+   'user rssave       di   mov    \ Address of return stack save area
+   rs-size #          si   sub    \ Bottom of return stack area
+
+   rs-size 4 / #      cx   mov    \ Size of return stack area (in longwords)
+   rep  movs
+
+   ret
+end-code
+
+
+hidden definitions
+
+d# 65 constant #signals
+#signals /n* buffer: old-signals
+
+defer save-state
+' save-state-signal to save-state
+
+: set-signal  ( handler signal# -- old-handler )
+   d# 92 syscall 2drop retval
+;
+: catch-signal  ( signal# -- )
+   save-state over  set-signal  ( signal# old-handler )
+   old-signals rot na+ !
+;
+: uncatch-signal  ( signal# -- )  old-signals over na+ @  swap set-signal drop  ;
+
+: uncatch-signals  ( -- )
+   d# 02 uncatch-signal	\ SIGINT
+   d# 04 uncatch-signal	\ SIGILL
+   d# 05 uncatch-signal	\ SIGTRAP
+   d# 07 uncatch-signal	\ SIGBUS
+   d# 08 uncatch-signal	\ SIGFPE, Divide by 0
+   d# 11 uncatch-signal	\ SIGSEGV
+;
+
+forth definitions
+: catch-signals  ( -- )
+   pssave drop  rssave drop	\ Force buffer allocation
+   [ 0 alloc-reg ] literal alloc-mem is cpu-state
+
+   d# 02 catch-signal	\ SIGINT
+   d# 04 catch-signal	\ SIGILL
+   d# 05 catch-signal	\ SIGTRAP
+   d# 07 catch-signal	\ SIGBUS
+   d# 08 catch-signal	\ SIGFPE, Divide by 0
+   d# 11 catch-signal	\ SIGSEGV
+;
+
+[ifdef] $save-forth
+: $save-forth  ( name$ -- )
+   uncatch-signals  $save-forth  catch-signals
+;
+[then]
+only forth also definitions
+
+\ Linux signal names
+
+string-array exception-names
+( 00 ) ," "
+( 01 ) ," "
+( 02 ) ," Interrupt"
+( 03 ) ," "
+( 04 ) ," Illegal Instruction"
+( 05 ) ," Trap"
+( 06 ) ," "
+( 07 ) ," Bus error"
+( 08 ) ," Floating point error or divide-by-0"
+( 09 ) ," "
+( 10 ) ," "
+( 11 ) ," "
+end-string-array
+
+: (.exception)  ( -- )
+   int#
+   dup d# 8 <=  if  exception-names ". cr  exit  then
+   push-decimal (u.) type cr pop-base
+;
+' (.exception) is .exception
+: print-breakpoint
+   .exception
+   interactive? 0=  if bye then	\ Restart only if a human is at the controls
+   ??cr quit
+;
+\ ' print-breakpoint is handle-breakpoint
+
+\ defer restart  ( -- )
+hidden also
+: sys-init
+   sys-init
+   catch-signals
+   restartable? off
+;
+only forth also definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Modified: cpu/x86/loadmach.fth
===================================================================
--- cpu/x86/loadmach.fth	2007-08-15 03:30:45 UTC (rev 546)
+++ cpu/x86/loadmach.fth	2007-08-15 20:20:01 UTC (rev 547)
@@ -53,6 +53,7 @@
 start-module			 \ Breakpointing
 fload ${BP}/cpu/x86/cpubpsup.fth \ Breakpoint support
 fload ${BP}/forth/lib/breakpt.fth
+fload ${BP}/cpu/x86/Linux/catchexc.fth  \ OS signal handling
 end-module
 
 \ LICENSE_BEGIN




More information about the OpenBIOS mailing list