
Hardware crashes
****************

This chapter describes how RISC OS Forthmacs copes with hardware exceptions 
such as Prefetch Errors, Address Errors, and Divide by Zero, and offers 
suggestions about debugging software which causes such problems.  

After a hardware exception (or a hardware-like trap) such as an Address Error, 
Prefetch Error, Divide-by-Zero, etc, RISC OS Forthmacs will attempt to 
recover.  The state of the registers and the stacks just before the crash are 
stored in a safe place, where it may be examined with showcrash. 

The current RISC OS Forthmacs version works fine with StrongARM cpus.  

All registers are saved to the registers buffer.  The bug vocabulary holds 
tools for handling the registers saved to this area.  There are objects called 
R0 R1 TOP SP PC PSR ... that can be inspected and changed by the user.  An 
example: 

         h# fffffff @
                  ------ an exception occurs
         showcrash
         top .    h# 8000 to top
         showcrash  top .
         (restart

This is used by several debugger tools and can be freely extended by user 
applications.  


Error handling
==============

The error-handling is rather complex in this implementation, all hardware- or 
hardware related errors are managed within RISC OS Forthmacs runtime system, 
processor-mode problems are hidden before you, and you will have to remember 
one single level of ERROR-MANAGING .  

All error conditions at last use ERROR-HANDLE later branching to the 
appropriate specialized error-handler.  You may redefine the handler according 
to your needs.  The error handlers: 

    : serve-error       \ ( exeption# -- ) standard error handler
        up@ main-task <> if drop -1 then throw ;
    
    defer handle-error      ' serve-error is handle-error
    defer handle-breakpoint ' serve-error is handle-breakpoint
    defer handle-escape     ' serve-error is handle-escape
    defer handle-data       ' serve-error is handle-data
    defer handle-address    ' serve-error is handle-address
    defer handle-prefetch   ' serve-error is handle-prefetch
    defer handle-div0       ' serve-error is handle-div0
    defer handle-illegal    ' serve-error is handle-illegal


handle-error, all RISC OS error calls go via this handler, use this to 
generate your own error conditions.  why will work perfectly with this.  

handle-breakpoint, a breakpoint instruction OS_BreakPt will go via this 
handler.  

handle-escape, escape conditions use this handler, currently this works like a 
RISC OS Forthmacs "reset" key outside the expect loop.  

handle-address, tried to access memory above $3ffffff.  

handle-data and handle-prefetch, access to data/instructions was aborted from 
the MMU, there wasn't any memory.  

handle-div0, tried to divide by zero 

handle-illegal, cpu ran into an undefined instruction 


Debugging Tools Glossary
========================


____ (restart       ( -- )                   bug            
Restart RISC OS Forthmacs after a hardware crash, the registers must have been 
saved before (this is done by the error-handler), (restart takes care about 
the cpu status.  

This can be used for developing debuggers, virtual memory managers etc.  

Implementation Note: For security reasons, (restart can't set supervisor mode.  
This restricts debuggers using this word to user mode debugging.  You could 
easily change this by adding the "set-supervisor-mode" swi in the (restart 
code.  
____

____ .registers     ( -- )                                  dot-registers
Displays the CPU registers values that were saved the last time that a 
breakpoint or exception occurred.  

The contents of the pc have been split to the program-counter pc and the 
status/flag register psr 
____

____ .sr            ( --  )                                 
Decodes and displays the contents of the ARM Status Register part of the pc 
register that was saved at the last breakpoint or exception.  The Status 
Register contains the Condition Codes, the Priority level and the interrupt 
level.  The display looks something like this: 
         nZcvif    user mode
"nZcvif" is the condition codes.  An upper case letter indicates that the 
corresponding bit is on.  In the case the "Z" (zero) bit is on and the other 
bits (Negative, Carry, oVerflow and the mode registers) are off.  
____

____ .stack         ( --  )                                 dot-stack
Displays the Data Stack saved at the last breakpoint or exception.  If the 
breakpoint occurred as a result of a RISC OS signal, the system may have been 
executing a system call at the time of the signal.  If so, there may be extra 
stuff on the stack such as C procedure activation frames.  
____

____ ftrace         ( -- )                                  
Display the return stack after a crash, if the return stack pointer was 
outside the RISC OS Forthmacs stack, there will only rudimentary information 
be given.  Tries to give not the cfa's but the words real names.  
____

____ handle-address  ( --  )                 Deferred, System  
This handler is used whenever an address exception has happened, mostly cause 
by a wrong address using @ ! etc.  

RISC OS Forthmacs has a common error handler for all kinds of errors.  This 
handler takes care of cpu state, operating system level etc.  All register 
data can be found in REGISTERS , r0 at the lowest address.  The stacks are 
saved at RSSAVE and PSSAVE .  

See: showcrash At it's end it jumps into the error-specific handler, by 
default this is SERVE-ERROR in all cases, but you can install your own error 
handling code instead.  The cpu level debugger uses handle-breakpoint, virtual 
memory could be implemented easily using handle-data and handle-address. 

See: showcrash 
____

____ handle-breakpoint  ( --  )              Deferred, System  
This handler is executed whenever a OS_Breakpt instruction was trapped.  Use 
this for more advanced debugging tools.  

See: handle-address 
____

____ handle-data    ( --  )                  Deferred, System  
This handler is used whenever a data abort has happened, mostly cause by a 
wrong address using @ ! etc.  

See: handle-address 
____

____ handle-div0    ( --  )                  Deferred, System  
This (emulated) exception is executed when a divide by zero error has 
happened.  

See: handle-address 
____

____ handle-error   ( --  )                  Deferred, System  
This handler is used when errors requested by you take place.  Use this for 
your application specific error handling.  

See: handle-address 
____

____ handle-escape  ( --  )                  Deferred, System  
This handler is used when an escape condition has happened.  Escape conditions 
can be generated by pressing the Ctrl-Sh-F12 key.  


See: handle-address 
____

____ handle-illegal  ( --  )                 Deferred, System  
This handler is used whenever the cpus should execute an an undefined opcode 
caused by executing code in nirvana or code-field areas.  

See: handle-address handle-prefetch handle-error 
____

____ handle-prefetch  ( --  )                Deferred, System  
This handler is used whenever a prefetch abort has happened, usually caused by 
executing code in nirvana.  

See: handle-address 
____

____ registers      ( -- addr  )             bug            
The address of a buffer holding all register contents after the last 
exception.  
____

____ r0             ( -- n )                 bug            
n is the value contained in the saved copy of register r0.  RR0 may be 
modified with the to command.  Other data register names are RR0, RSP etc.  

See: to .registers 
____

____ pc             ( -- n )                 bug            
n is the value contained in the saved copy of the Program Counter.  This value 
is used as the address where the program is restarted for the step , steps , 
and continue commands.  pc may be modified with the to command.  Pipeline 
effects have been cleared.  
____

____ sp             ( -- n )                 bug            
n is the value contained in the saved copy of the Stack Pointer.  
____

____ psr            ( -- n )                 bug            
n is the value contained in the saved copy of the Status Register.  The Status 
Register contains the Condition Codes, the Priority level and the Interrupt 
level.  RSR may be modified with the to command.  

See: .sr 
____

____ up             ( -- n )                 bug            
n is the value contained in the saved copy of the User-area Pointer.  

See: RR0 
____

____ showcrash      ( --  )                                 
Displays all the information saved at the last breakpoint or exception 
including the registers (as in .registers), the data stack (as in .stack), and 
the return stack (as in ftrace). 
____
