# System State: Overview

The functions contained in this category are mainly used to handle the CPSR (Current Program Status Register) and state inside the co-processor 15 (CP15).

## CPSR

The CPSR is a status register that internally contains information on the status of logical operations, the disable flag for FIQ and IRQ interrupts, and the processor mode.

The `N`, `Z`, `C`, and `V` flags are conditional bits set by the results of logical operations. The `N` flag is set when the result of an operation is a negative value; the `Z` flag is set when the result of an operation is zero; the `C` flag is set when a carry occurs during an operation; and the `V` flag is set when an overflow occurs during an operation.

The `Q` flags `QADD`, `QSUB`, `QDADD`, and `QDSUB` are used to find out when a saturation arithmetic operation caused an overflow.

IRQ interrupts are disabled if the `I` flag is set.

FIQ interrupts are disabled if the `F` flag is set.

The `T` flag indicates the current processor state (ARM or Thumb), which will be Thumb when the `T` flag is set.

The mode bits are the processor mode and take one of the following seven values. The TWL system normally runs in system mode. It runs in IRQ mode during an interrupt.

mode bits | Mode
--- | ---
0b10000 | User mode
0b10001 | FIQ mode
0b10010 | IRQ mode
0b10011 | Supervisor mode
0b10111 | Abort mode
0b11011 | Undefined mode
0b11111 | System mode

## Interrupt State (IRQ)

`OS_EnableInterrupts()` clears the I bit. In other words, it enables IRQ interrupts.

`OS_DisableInterrupts()` sets the I bit. In other words, it disables IRQ interrupts.

`OS_RestoreInterrupts()` sets the I bit to a designated state. In other words, it restores the IRQ interrupts to a designated state.

These functions return the state before it is changed. This is used to restore the original state with `OS_RestoreInterrupts` after `OS_EnableInterrupts` and `OS_DisableInterrupts` have changed the state and some processing has occurred. As shown in the following example, an interrupt state will usually be changed and then recovered; these operations are used as a pair.

> `Example:
> OSIntrMode enabled = OS_EnableInterrups();
> :
> (void)OS_RestoreInterrupts( enabled );`

## Interrupt State (IRQ and FIQ)

> (CAUTION)
> Since FIQ interrupts are used with the debug tool, the application cannot use them. Also, applications normally have no need to use them. The functions for handling FIQs, as described here, were created for use with only certain types of software, such as system tools and middleware.

Similar to the IRQ interrupt functions, there are functions for configuring both the IRQ interrupts and the FIQ interrupts at the same time.

`OS_EnableInterrupts_IrqAndFiq()` clears the `I` and `F` bits. In other words, it enables IRQ interrupts and FIQ interrupts.

`OS_DisableInterrupts_IrqAndFiq()` sets the `I` and `F` bits. In other words, it enables IRQ interrupts and FIQ interrupts.

`OS_RestoreInterrupts()_IrqAndFiq()` sets the `I` and `F` bits to designated states. In other words, it restores the IRQ interrupts and FIQ interrupts to designated states.

The function groups related to these IRQ interrupts and FIQ interrupts use `OS_RestoreInterrupts_IrqAndFiq()` for state recovery, and Enable / Restore or Disable / Restore are normally used as a pair.

> Example:
> `OSIntrMode enabled = OS_EnableInterrups_IrqAndFiq();
> :
> (void)OS_RestoreInterrupts_IrqAndFiq( enabled );`

## Getting the State (IRQ, Processor Mode)

Use `OS_GetCpsrIrq()` to get the current IRQ interrupt configuration.

Use `OS_GetProcMode()` to get the current processor mode. Operations are normally performed in system mode.

## Halting the CPU

When the CPU is idle, you can reduce power consumption by halting the CPU. It can receive interrupts and recover even if it is in this halt state. The function for halting is `OS_Halt()` on both ARM9 and ARM7.

It is not necessary for the application side to be aware of this, but the ARM9 processor goes into the HALT state with the CP15 function, while the ARM7 side uses a system call.

## Stopping the Program

`OS_Terminate()` has been prepared as a function for stopping the execution of the current program. This function disables IRQ interrupts internally and becomes a loop that calls `OS_Halt()`. There will be no transition to other threads and no interrupt handler will be called after entering the loop. This function will trap the ARM9 processor in a loop, but the ARM7 will continue running.

`OS_Exit()` and `OS_FExit()` are also functions for stopping execution of programs. Internally, they display the specified status and call `OS_Terminate()`. These functions can stop `loadrun` or `loadrun.TWL` by displaying a string.

The functions `OS_Panic()` and `OS_FPanic()` are similar. These functions display the position of the halted program using the source file name and line number. They also display some specified string. These functions are used for debugging purposes; in FINALROM builds, they become equivalent to `OS_Terminate()`.

> Example:
> `OS_Terminate();
> OS_Exit( 100 );
> OS_Panic( "now stop (x=%d)", myX );`

## Waiting

`OS_SpinWait()`, `OS_SpinWaitCpuCycles()`, and `OS_SpinWaitSysCycles()` wait for a designated period of time by looping in accordance with the CPU. However, since the CPU only loops, when an interrupt occurs it may not take longer than the designated time to return from the function. Interpret this as the "lower-limit wait time" for the designated time.

The `OS_SpinWait` function takes NITRO compatibility into consideration; it is based on a ~67-MHz ARM9 and a ~33-MHz ARM7. The ARM9's double-speed mode has no effect on this.

The `OS_SpinWaitCpuCycles` function is based on the CPU cycles. This will be approximately 134 MHz when the ARM9 is running at double speed.

The `OS_SpinWaitSysCycles` function uses the base cycle (~33 MHz) as a standard.

## See Also

`An Overview of OS Functions (System State)`

## Revision History

2008/05/23 Added a note on `OS_Panic`.
2007/09/27 Added `OS_SpinWaitCpuCycles` and `OS_SpinWaitSysCycles`.
2004/12/14 Revised terminology and word endings.
2004/11/09 Initial version.

CONFIDENTIAL