<!-- Forthmacs Formatter generated HTML V.2 output -->
<html>
<head>
<title>Hardware crashes</title>
</head>
<body>
<h1>Hardware crashes</h1>
<hr>
<p>
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.  
<p>
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 <code><A href="_smal_BU#2FC">showcrash</A>.</code> 
<p>
The current RISC OS Forthmacs version works fine with StrongARM cpus.  
<p>
All registers are saved to the <code><A href="_smal_BI#50">registers</A></code> 
buffer.  The <code><A href="_smal_AS#192">bug</A></code> <code><A href="_smal_BQ#358">vocabulary</A></code> 
holds tools for handling the registers saved to this area.  There are objects 
called <strong>r0 r1 top sp pc psr ...</strong> that can be inspected and 
changed by the user.  An example: 
<p>
<p><pre>       h# fffffff @</pre><p>
<p><pre>                ------ an exception occurs</pre><p>
<p><pre>       showcrash</pre><p>
<p><pre>       top .    h# 8000 to top</pre><p>
<p><pre>       showcrash  top .</pre><p>
<p><pre>       (restart</pre><p>
<p>
This is used by several debugger tools and can be freely extended by user 
applications.  
<p>
<p>
<h2>Error handling</h2>
<p>
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 <strong>error-managing</strong> .  
<p>
All error conditions at last use <strong>error-handle</strong> later branching 
to the appropriate specialized error-handler.  You may redefine the handler 
according to your needs.  The error handlers: 
<p>
<p><pre>
    : serve-error       \ ( exeption# -- ) standard error handler
        up@ main-task &lt;&gt; 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
</pre><p>
<p>
<p>
<code><A href="_smal_BE#4C">handle-error</A>,</code> all RISC OS error calls go 
via this handler, use this to generate your own error conditions.  <code><A href="_smal_AC#362">why</A></code> 
will work perfectly with this.  
<p>
<code><A href="_smal_BB#49">handle-breakpoint</A>,</code> a breakpoint 
instruction OS_BreakPt will go via this handler.  
<p>
<code><A href="_smal_BF#4D">handle-escape</A>,</code> escape conditions use this 
handler, currently this works like a RISC OS Forthmacs "reset" key outside the <code><A href="_smal_AK#21A">expect</A></code> 
loop.  
<p>
<code><A href="_smal_BA#48">handle-address</A>,</code> tried to access memory 
above $3ffffff.  
<p>
<code><A href="_smal_BC#4A">handle-data</A></code> and <code><A href="_smal_BH#4F">handle-prefetch</A>,</code> 
access to data/instructions was aborted from the MMU, there wasn't any memory.  
<p>
<code><A href="_smal_BD#4B">handle-div0</A>,</code> tried to divide by zero 
<p>
<code><A href="_smal_BG#4E">handle-illegal</A>,</code> cpu ran into an undefined 
instruction 
<p>
<p>
<h2>Debugging Tools Glossary</h2>
<p>

<hr><h3><A name="43">(restart</A></h3> <h5> ( -- )
 Extra: bug
</h5>
<br>
Restart RISC OS Forthmacs after a hardware crash, the registers must have been 
saved before (this is done by the error-handler), <code><A href="_smal_AT#43">(restart</A></code> 
takes care about the cpu status.  
<p>
This can be used for developing debuggers, virtual memory managers etc.  
<p>
Implementation Note: For security reasons, <code><A href="_smal_AT#43">(restart</A></code> 
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 <code><A href="_smal_AT#43">(restart</A></code> 
code.  

<hr><h3><A name="44">.registers</A></h3> <h5> ( -- )</h5>
<br>
Displays the CPU registers values that were saved the last time that a 
breakpoint or exception occurred.  
<p>
The contents of the <code><A href="_smal_BK#52">pc</A></code> have been split to 
the program-counter <code><A href="_smal_BK#52">pc</A></code> and the 
status/flag register <code><A href="_smal_BM#54">psr</A></code> 

<hr><h3><A name="45">.sr</A></h3> <h5> ( --  )</h5>
<br>
Decodes and displays the contents of the ARM Status Register part of the <code><A href="_smal_BK#52">pc</A></code> 
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: 
<p><pre>       nZcvif    user mode</pre><p>
"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.  

<hr><h3><A name="46">.stack</A></h3> <h5> ( --  )</h5>
<br>
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.  

<hr><h3><A name="47">ftrace</A></h3> <h5> ( -- )</h5>
<br>
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.  

<hr><h3><A name="48">handle-address</A></h3> <h5> ( --  )
 Extra: Deferred, System
</h5>
<br>
This handler is used whenever an address exception has happened, mostly cause by 
a wrong address using <strong>@ !</strong> etc.  
<p>
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 <strong>registers</strong> , r0 at the lowest address.  The 
stacks are saved at <strong>rssave</strong> and <strong>pssave</strong> .  

See: <code><A href="_smal_BU#2FC">showcrash</A></code> At it's end it jumps into 
the error-specific handler, by default this is <strong>serve-error</strong> in 
all cases, but you can install your own error handling code instead.  The cpu 
level debugger uses <code><A href="_smal_BB#49">handle-breakpoint</A>,</code> 
virtual memory could be implemented easily using <code><A href="_smal_BC#4A">handle-data</A></code> 
and <code><A href="_smal_BA#48">handle-address</A>.</code> 

See: <code><A href="_smal_BU#2FC">showcrash</A></code> 

<hr><h3><A name="49">handle-breakpoint</A></h3> <h5> ( --  )
 Extra: Deferred, System
</h5>
<br>
This handler is executed whenever a OS_Breakpt instruction was trapped.  Use 
this for more advanced debugging tools.  

See: <code><A href="_smal_BA#48">handle-address</A></code> 

<hr><h3><A name="4A">handle-data</A></h3> <h5> ( --  )
 Extra: Deferred, System
</h5>
<br>
This handler is used whenever a data abort has happened, mostly cause by a wrong 
address using <strong>@ !</strong> etc.  

See: <code><A href="_smal_BA#48">handle-address</A></code> 

<hr><h3><A name="4B">handle-div0</A></h3> <h5> ( --  )
 Extra: Deferred, System
</h5>
<br>
This (emulated) exception is executed when a divide by zero error has happened.  

See: <code><A href="_smal_BA#48">handle-address</A></code> 

<hr><h3><A name="4C">handle-error</A></h3> <h5> ( --  )
 Extra: Deferred, System
</h5>
<br>
This handler is used when errors requested by you take place.  Use this for your 
application specific error handling.  

See: <code><A href="_smal_BA#48">handle-address</A></code> 

<hr><h3><A name="4D">handle-escape</A></h3> <h5> ( --  )
 Extra: Deferred, System
</h5>
<br>
This handler is used when an escape condition has happened.  Escape conditions 
can be generated by pressing the Ctrl-Sh-F12 key.  
<p>

See: <code><A href="_smal_BA#48">handle-address</A></code> 

<hr><h3><A name="4E">handle-illegal</A></h3> <h5> ( --  )
 Extra: Deferred, System
</h5>
<br>
This handler is used whenever the cpus should execute an an undefined opcode 
caused by executing code in nirvana or code-field areas.  

See: <code><A href="_smal_BA#48">handle-address</A></code> <code><A href="_smal_BH#4F">handle-prefetch</A></code> 
<code><A href="_smal_BE#4C">handle-error</A></code> 

<hr><h3><A name="4F">handle-prefetch</A></h3> <h5> ( --  )
 Extra: Deferred, System
</h5>
<br>
This handler is used whenever a prefetch abort has happened, usually caused by 
executing code in nirvana.  

See: <code><A href="_smal_BA#48">handle-address</A></code> 

<hr><h3><A name="50">registers</A></h3> <h5> ( -- addr  )
 Extra: bug 
</h5>
<br>
The address of a buffer holding all register contents after the last exception.  

<hr><h3><A name="51">r0</A></h3> <h5> ( -- n )
 Extra: bug
</h5>
<br>
n is the value contained in the saved copy of register r0.  RR0 may be modified 
with the <code><A href="_smal_BN#325">to</A></code> command.  Other data 
register names are RR0, RSP etc.  

See: <code><A href="_smal_BN#325">to</A></code> <code><A href="_smal_AU#44">.registers</A></code> 

<hr><h3><A name="52">pc</A></h3> <h5> ( -- n )
 Extra: bug
</h5>
<br>
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 <code><A href="_smal_AF#65">step</A></code> 
, <code><A href="_smal_AG#66">steps</A></code> , and <code><A href="_smal_AA#60">continue</A></code> 
commands.  <code><A href="_smal_BK#52">pc</A></code> may be modified with the <code><A href="_smal_BN#325">to</A></code> 
command.  Pipeline effects have been cleared.  

<hr><h3><A name="53">sp</A></h3> <h5> ( -- n )
 Extra: bug 
</h5>
<br>
n is the value contained in the saved copy of the Stack Pointer.  

<hr><h3><A name="54">psr</A></h3> <h5> ( -- n )
 Extra: bug 
</h5>
<br>
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 <code><A href="_smal_BN#325">to</A></code> 
command.  

See: <code><A href="_smal_AV#45">.sr</A></code> 

<hr><h3><A name="55">up</A></h3> <h5> ( -- n )
 Extra: bug 
</h5>
<br>
n is the value contained in the saved copy of the User-area Pointer.  

See: RR0 

<hr><h3><A name="56">showcrash</A></h3> <h5> ( --  )</h5>
<br>
Displays all the information saved at the last breakpoint or exception including 
the registers (as in <code><A href="_smal_AU#44">.registers)</A>,</code> the 
data stack (as in <code><A href="_smal_AW#46">.stack)</A>,</code> and the return 
stack (as in <code><A href="_smal_AX#47">ftrace)</A>.</code> 
</body>
</html>
