Kernel callout categories

The startup library provides kernel callouts that look after different categories of tasks. You can use these callouts as models when you write your own kernel callouts.

Source code

The source code for these kernel callouts is in the source code directories, originally installed in bsp_working_dir/src/hardware/startup/lib/. This directory and its subdirectories include generic code, as well as processor-specific directories with processor-specific kernel callouts. Before you begin writing a kernel callout, check these directories to see if a callout is already available:

In the CPU-dependent level of the tree for all the source files, look for files with names that match the pattern: callout_*.[sS]. These files are the callouts provided by the library. Whether a file ends in .s or .S depends on whether it's sent through the C preprocessor before being handed off to an assembler. For simplicity, we'll simply refer to them as .s files.

The file names break down further as follows: callout_category_device.s, where category is one of the following categories:

and where device identifies the unique hardware the callouts were written for.

Typically, the kernel uses or doesn't use all the kernel callouts in any particular source file. For example, the callout_debug_8250.s file contains the display_char_8250(), poll_key_8250(), and break_detect_8250() kernel callouts, which are all used for working with an 8250-style UART chip.

For more information about writing a kernel callout, see Writing a kernel callout in this chapter.

Macros for kernel callouts

All kernel callouts use macros found in callout.ah to define their start and end.

For example, the following excerpt describes the interrupt_id_405() kernel callout:

CALLOUT_START interrupt_id_405, 0, 0 
	li %r14,-1     
	mfdcr %r5,PPC405_DCR_UIC0_MSR 
	...
	andc %r4,%r4,%r5 
	mtdcr PPC405_DCR_UIC0_ER,%r4 
	1: 
CALLOUT_END interrupt_id_405 

The CALLOUT_START parameters specify the following information:

  • The name of the kernel callout (for example, interrupt_id_405)
  • The address of a variable that specifies the amount of static read/write storage the callout requires, or 0, if no storage is required
  • The name of a patch routine that modifies the callout code after the startup code copies it to kernel memory, or 0, if the callout requires no patch routine

CALLOUT_END specifies the CALLOUT_START to match (for example, interrupt_id_405).

For more information on the kernel callout macros and patch routines, see Kernel callout start and end macros and Patching the kernel callout code in this chapter.

Patch routines

Kernel callout code references addresses using routines that edit code after it has been copied into system memory. When a kernel callout uses one of these routines, it is specified using the CALLOUT_START constant. If the kernel callout code only needs to access CPU registers, a patch routine is not required.

For example, in the following excerpt from a display_char() kernel callout, the CALLOUT_START macro's third argument invokes the routine patch_debug(). This routine replaces the 0x1234 and 0x5678 with the base address of the serial controller register:

CALLOUT_START display_char_5200, 0, patch_debug
lis   %r6,0x1234
ori   %r6,%r6,0x5678

For further discussion of these routines and when they are necessary, see Patching the kernel callout code in this chapter.