Output information about the specified address (or that of the last abort).
Uses SWI DebugTools_Where.
Examples:
*Where
*Where 0240DD84
List the contents of the software vectors.
Uses SWI DebugTools_Vectors.
Examples:
*Vectors
*Vectors 2E
*Vectors IrqV
List the contents of the Kernel's CallAfter and CallEvery list.
Uses SWI DebugTools_Tickers.
Examples:
*Tickers
List the contents of the Kernel device vectors.
Uses SWI DebugTools_IRQDevices.
Examples:
*IRQDevices
Execute the specified *command and place any error into the X$Error system variable (if it is currently unset). Do not return the error.
No equivalent SWI call.
Examples:
*X Pin Boot:Choices 180 154
*X Wipe rm ~cfr~v
Canonicalise the specified filename and place the result in a system variable.
No equivalent SWI call.
Examples:
*Canonical Root$Dir Boot:^
*Canonical My$Scrap Waste:Basket.12Mar2003.Scrap
This command can be used to both activate and deactivate the IRQ timing mechanism, and to output a table of statistics.
Parameter: | Function: |
---|---|
None | Output a table of statistics (see below) |
0 | Deactivate the timing mechanism (off by default) |
1 | Activate the timing mechanism |
2+ | Reserved - do not use |
If the parameter "1" is passed when the timing mechanism is already active, this command will not do anything. If the parameter "0" is passed when the timing mechanism is already inactive, this command will not do anything.
When no parameter is passed, this command will check to see if the timing mechanism is active. If not, it will activate it. If active, this command outputs a table of information on the number of times in the last second that each device driver for each IRQ device number was entered. It also shows the percentage of CPU use for each device driver.
Does not need to use SWI DebugTools_IRQInfo.
Examples:
*IRQInfo 1
Output a dump of our count of how many times we have seen each device pass along IrqV since the last call to this *command. Reset all counters to zero after reading them.
Does not need to use SWI DebugTools_UnknownIRQs.
Examples:
*UnknownIRQs
When a module cannot be killed, it is usually because the module finalisation code is returning an error. This *command will attempt to replace the finalisation code offset in the specified module's header with zero and then kill the module. Faulty ROM modules clearly cannot be killed using this method because their module header is in read-only memory.
WARNING: removing the module finalisation code and then killing the module can lead to system instability due to the fact that any system resources claimed by the module (i.e. CallBacks, Events, Vectors, RMA, etc) are not freed. This *command is aimed for use during module development only.
Does not use any DebugTools SWI calls.
Examples:
*RMDie FrontEnd
This command is similar to the *RMDie command, but it does not attempt to kill the specified module. It will reset all module header words in the specified module to zero, apart from the module title string and module help string. Faulty ROM modules clearly cannot be killed using this method because their module header is in read-only memory.
The module is left in the module chain so that any system resources claimed by that module can continue to operate as expected.
The module will have its title and help strings replaced with a string of
the form "Dead<num>
", where num
is an eight-digit hexadecimal number, incremented after each call to
*RMRemove. As the module is given a new title string, it can be killed with
*RMKill later. It also allows that module to be re-loaded.
Note: if the module is killed, it will leak an additional 16 bytes of RMA used to store the new title and help string. This is likely to be of minor impact when compared to the other system resources leaked by removing the module's finalisation code! Refer to the warning for *RMDie.
Does not use any DebugTools SWI calls.
Examples:
*RMRemove FrontEnd
As with the UNIX command of the same name, this command push the currently selected directory (CSD) onto a stack and then set the specified directory (if any) as the CSD.
Does not use any DebugTools SWI calls.
Examples:
*pushd Boot:Choices.Boot.Tasks
As with the UNIX command of the same name, this command will change the currently selected directory (CSD) to the top one off the directory stack (if any). This directory will be removed from the stack.
Does not use any DebugTools SWI calls.
Examples:
*popd
As with the UNIX command of the same name, this command outputs the (canonicalised) currently selected directory (CSD) to all active output streams.
Does not use any DebugTools SWI calls.
Examples:
*pwd
Evaluate the specified expression and output the result as either a string (if that is the type) or as eight-digit hexadecimal (if the result is an integer).
Does not use any DebugTools SWI calls.
Examples:
*EvalHex &00FFFF00 AND (&01F00000 + &CD0)
Evaluate the specified expression and output the result as either a string (if that is the type) or as 32 bit binary (if the result is an integer).
Does not use any DebugTools SWI calls.
Examples:
*EvalBin 2_10001011 EOR (2_11100111 + 53730)
Given an address, try to sensibly interpret the context of that address. It returns values in R0-R3 to indicate information about the specified address.
A list of the current area types and return values are:
R0 | = 0 |
R1 | = R1 on entry rounded-down to nearest page boundary |
R2 | = offset of R1 on entry from page boundary |
R3 | = 0 |
R0 | = 1 |
R1 | = base address of module |
R2 | = offset of R1 on entry from module base |
R3 | = pointer to module title string |
R0 | = 2 |
R1 | = base address of module workspace |
R2 | = offset of R1 on entry from workspace base |
R3 | = pointer to module title string |
R0 | = 3 |
R1 | = base address of dynamic area |
R2 | = offset of R1 on entry from area base |
R3 | = pointer to dynamic area name string |
R0 | = 4 |
R1 | = base address of dynamic area |
R2 | = offset of R1 on entry from area base |
R3 | = pointer to dynamic area name string |
R0 | = 5 |
R1 | = as R1 on entry |
R2 | = 0 |
R3 | = 0 |
R0 | = 6 |
R1 | = ROM base address |
R2 | = offset of R1 on entry from ROM base |
R3 | = 0 |
R0 | = 7 |
R1 | = as R1 on entry |
R2 | = 0 |
R3 | = 0 |
R0 | = 8 |
R1 | = &8000 |
R2 | = offset of R1 on entry from &8000 |
R3 | = 0 |
R0 | = 9 |
R1 | = as R1 on entry |
R2 | = 0 |
R3 | = 0 |
R0 | = flags word (zero) |
R1 | = address to check |
R0 | = area type code (or pointer to error block) |
R1 | = base address of area |
R2 | = offset of R1 on entry into area |
R3 | = additional area info (depends upon R0 on exit) |
R4-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
Given an address (or the address of the last abort), output an analysis of where that address is (using the AddressInfo SWI).
R0 | = flags word |
bit 0 | 0 - R1 contains address to inspect |
1 - Inspect address of the last exception | |
bits 1-31 | - should be zero |
R1 | = address to check (if R0:0 is clear on entry) |
R0 | = corrupted (or pointer to error block) |
R1-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
Output information on the claimants of each of the software vectors in a human-readable format.
R0 | = flags word |
bit 0 | 0 - list contents of all vectors |
1 - list contents of vector number in R1 | |
bits 1-31 | - should be zero |
R1 | = vector number to enumerate (if R0:0 set on entry) |
R0 | = corrupted (or pointer to error block) |
R1-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
Enumerate all of the currently pending CallAfters and CallEverys in a human-readable format.
R0 | = flags word (zero) |
R0 | = corrupted (or pointer to error block) |
R1-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
Output the contents of the Kernel's device driver vector in a human-readable format. This may not be available on early Kernels.
R0 | = flags word (zero) |
R0 | = preserved (or pointer to error block) |
R1-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
Return a pointer to a table of information about the current device drivers installed on the Kernel's device vector. This is a copy of the table which is maintained by the patch code on the Kernel's interrupt despatch code.
The table is refreshed once every second. The format is:
Bytes: | Contents: |
---|---|
0-3 | IRQ 0 - number of 2 MHz cycles consumed by driver |
4-7 | IRQ 0 - number of times driver was called |
8-11 | IRQ 1 - number of 2 MHz cycles... |
12-15 | IRQ 1 - number of times... |
... | ... |
128-131 | IRQs above 15 - number of 2 MHz cycles... |
132-135 | IRQs above 15 - number of times... |
Note: calls to this SWI will return zero in R0 if the IRQ timing mechanism has not yet been activated with a call to *IRQInfo. Timing information will only be updated once a second, so calls within the first 99 cs after activating the timing mechanism will return a table filled with zeros.
R0 | = flags word (zero) |
R0 | = pointer to table of IRQ information or zero if none is available |
R1 | = size of the table (bytes) |
R2-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
Return a pointer to a table of information hit counts for each device number from our code sat on IrqV. The table is reset to zero after each call to *UnknownIRQs.
Bytes: | Contents: |
---|---|
0-3 | Counter for IRQ device 0 |
4-7 | Counter for IRQ device 1 |
... | ... |
124-127 | Counter for IRQ device 31 |
R0 | = flags word (zero) |
R0 | = pointer to table or zero if none is available |
R1 | = size of the table (bytes) |
R2-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
This SWI call allows the specified code to be added onto a vector of code to call whenever the specified OS SWI call is made. SWI DebugTools_ClaimOSSWI will add the code specified in R1 to the head of the vector for the OS SWI specified in R0. It will remove all other claimants on the vector with identical values of both R1 and R2 on entry to this SWI.
The value passed in R2 to this SWI will be passed into the claimant's code in R12 whenever the claimant is entered - it is the claimant's private word. Other registers are defined below. Note: the claimant is the code which resides on a particular OS SWI vector, the caller is the code which issued the OS SWI.
See the notes section for more information.
R0 | = OS SWI number (flags in top 8 bits - should be zero) |
R1 | = pointer to code to add |
R2 | = value to be passed in R12 to code |
R0 | = corrupted (or pointer to error block) |
R1-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
This SWI behaves in much the same way as DebugTools_ClaimOSSWI, except that any previous claimants on the vector are preserved, even if they were added with identical values of R1 and R2.
See the notes section for more information.
R0 | = OS SWI number (flags in top 8 bits - should be zero) |
R1 | = pointer to code to add |
R2 | = value to be passed in R12 to code |
R0 | = corrupted (or pointer to error block) |
R1-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
This SWI will remove the first (head first, tail last) instance of a claimant from the specified OS SWI vector, which was added with identical values in R1 and R2.
If no match is found, the error "Bad OS SWI release" will be returned. If an attempt is made to remove the Kernel (tail) claimant from any vector, the error "You cannot release the Kernel claimant" will be returned.
See the notes section for more information.
R0 | = OS SWI number (flags in top 8 bits - should be zero) |
R1 | = pointer to code to remove |
R2 | = value passed in R2 when added |
R0 | = corrupted (or pointer to error block) |
R1-R9 | = preserved |
V flag | = set if R0 is a pointer to an error block |
The following are additional notes concerning the usage of the DebugTools SWIs ClaimOSSWI, AddToOSSWI and ReleaseOSSWI.
On entry to the claimant's code:R0-R9 | = as for the claimed SWI |
R10 | = copy of the caller's CPSR |
R11 | = SWI number |
R12 | = private word (as passed in R2 to ClaimOSSWI) |
R13 | = full-descending supervisor stack pointer |
R14 | = address to return to for passing-on the SWI call |
CPSR_f | = undefined |
CPSR_c | = ARM mode, SVC26 or SVC32, IRQs/FIQs as for caller |
The Kernel (i.e. the original claimant of the SWI) will always be at the tail of the vector. Thus, a claimant may wish to either modify the registers before passing the SWI call on to the Kernel, or it may wish to claim the SWI call to stop it from being passed-on to the Kernel.
To pass-on the OS SWI call on exit from the claimant's code, use:
MOV PC,LR
and not MOVS PC,LR
To claim the OS SWI call on exit from the claimant's code, use:
LDMFD R13!,{PC}
and not LDMFD R13!,{PC}^
If you want to return an error to the caller, you must set R0 to be a pointer to the error block as normal and set the V bit in R10, not R14. This is because the CPSR is restored from the value in R10 before the SWI returns to the caller.
The exit conditions for passing-on and claiming an OS SWI call are described below.
On exit from the claimant's code (passing-on the call):R0-R9 | = may be modified for next claimant |
R10 | = may be modified for next claimant |
R11 | = must be preserved |
R12 | = may be corrupted |
R13 | = must be preserved |
R14 | = may be corrupted |
CPSR_f | = may be corrupted |
CPSR_c | = must be preserved |
R0-R9 | = may be modified |
R10 | = full CPSR to assert on return to caller |
R11 | = may be corrupted |
R12 | = may be corrupted |
R13 | = R13 on entry +4 (pulled LR to claim) |
R14 | = may be corrupted |
CPSR_f | = may be corrupted |
CPSR_c | = must be preserved |
When you claim, add to or release an OS SWI using the DebugTools SWIs, there are some additional constraints that you should be aware of: