The kernel uses the debug callouts when it needs to print out some internal debugging information or encounters a fault.
The kernel uses these callouts to interact with a serial port, console, or other device to output debug or instrumentation information. For example, a display_msg command in a boot image startup script can cause procnto to use a debug kernel callout to output a message similar to the following one:
Running default qnxbasedma.build...
We recommend that when you are working on a startup program you start by getting a debug kernel callout working. The ability to output messages to a device helps you debug code as you add or modify it.
The kernel uses these callouts when it needs to interact with a serial port, console, or other device. Only the display_char() callout is required; the others are optional.
This kernel callout takes the char (character) passed into it in the r4 register, and outputs it to the serial controller.
The CALLOUT_START macro's third argument invokes the patch_debug() routine. This routine replaces the 0x1234 and 0x5678 with the base address of the serial controller register.
The lis (load immediate and shift) and the ori (OR immediate) instructions load the base address of the UART registers into r6:
CALLOUT_START display_char_5200, 0, patch_debug lis %r6,0x1234 ori %r6,%r6,0x5678
Disable interrupts:
loadi %r9,PPC_MSR_EE mfmsr %r8 andc %r9,%r8,%r9 mtmsr %r9 isync
Loop until the Transmit Ready bit has been set:
1: lwz %r0,MGT5200_PSC_SR(%r6) andis. %r0,%r0,MGT5200_PSC_SR_TXRDY beq 1b
Store byte (the char passed in by kernel in r4) in the Transmit Byte register:
stb %r4,MGT5200_PSC_TB(%r6) eieio
Re-enable interrupts, then branch to the link register and continue executing at the instruction that follows the call to this routine:
mtmsr %r8 isync blr
End of callout marker:
CALLOUT_END display_char_5200