[ Bottom of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]

Understanding the Diagnostic Subsystem for AIX

Test Unit 64-bit Porting Guide

Changes to the pdiagex kernel extension running under a 64-bit kernel were designed with the test unit developer in mind. Most of the changes required to port the test units are done at the Second Level Interrupt Handler (SLIH) level. For a test unit developer that has followed the architecture specified in this document, the changes are minor and will require minimal testing.

Before porting an existing set of test units, it is important to understand the test units application environment as well as the 64-bit C language data model and how it differs from the 32-bit model.

Test units execute as 32-bit applications under a 32-bit kernel and therefore only use 32-bit kernel extensions (pdiagex). This porting guide describes the required changes to the test units and SLIH in order to function under a 64-bit kernel. The test units will continue executing as 32-bit applications: only the SLIHs will be 64-bit applications.

C Language Data Model

The C language data model used in the 32-bit and 64-bit operating system environments are defined in the following table. You must consider the size of the data passed from the Test Units to the SLIHs and back, since sizes can change as they are passed from one environment to the other. Use special care when passing information in the form of structures or pointers.

C Type 32-bit Data Size 64-bit Data Size
char 8 bits 8 bits
short 16 bits 16 bits
int 32 bits 32 bits
long 32 bits 64 bits
long long 64 bits 64 bits
pointer 32 bits 64 bits

Makefile

To support 32-bit and 64-bit SLIHs, the SLIH Makefile has to be modified to build two executables; one for 32-bits that will remain named as it is today and one for the 64-bit SLIH which will have 64 appended to the name.

File Names Syntax Example
32-bit filename fcphal_intr
64-bit filename64 fcpthal_intr64

Makefile Source

Here is an example of what a common source 32-bit and 64-bit SLIH Makefile might look like:

Note
Replace the environment variables and file names with your own names to customize this example for your own use.

# @(#)17     1.1  src/idd/en_US/aixprggd/diagunsd/TU_64bit_port.htm, 
iddiagunsd, idd500 5/23/00 13:54:31
#

.include <${MAKETOP}bos/kernext/Kernext.mk>


TU_VPATH   = ${MAKETOP}/bos/diag/tu/tu_dir
VPATH      = ${MAKETOP}bos/kernel/exp:${MAKETOP}bos/kernext/exp:$TU_VPATH

# 32-bit version of load object
#
KERNEL_EXT      = your_intr

# 64-bit version of load object
#
KERNEL_EXT64    = your_intr64

IDIR            = /usr/lpp/diagnostics/slih/

# install list containing 32-bit and 64-bit version
#
ILIST           = your_intr your_intr64

OPT_LEVEL       =    -qlist -qsource

# entry point, import and export files for 32-bit version
#
your_intr_DEPENDS        = your_intr.exp
your_intr_ENTRYPOINT     = your_interrupt
your_intr_IMPORTS        = -bI:pdiagex.exp
your_intr_EXPORTS        = -bE:your_intr.exp

# entry point, import and export files for 64-bit version
# (common with 32-bit version)
your_intr64_DEPENDS      = your_intr.exp
your_intr64_ENTRYPOINT   = your_interrupt
your_intr64_IMPORTS      = -bI:pdiagex.exp \
                                 pdiagex64.exp
your_intr64_EXPORTS      = -bE:your_intr.exp

# object list definition for 32-bit version
#
your_intr_OFILES     =  your_intr.o

# object list definition for 64-bit version (common objects
# across 32-bit and 64-bit versions), with 64-bit objects
# renamed to .64o
#
your_intr64_OFILES   =  your_intr.64o

INCFLAGS   = -I${MAKETOP}/bos/diag/tu/tu_dir \
             -I${MAKETOP}bos/usr/include
LIBS       = ${KERNEXT_LIBS}


.include <${RULES_MK}>

SLIH Conversion Tips

To achieve a clean SLIH conversion, pay special attention to the following:

SLIH Conversion Required Changes

The following required changes must be applied to all SLIHs being ported to 64-bit kernel:

  1. Performing Read Operations to a Device

    All instances of pdiag_dd_read will have to be duplicated with pdiag_dd_read_64 for 64-bit. Every place where pdiag_dd_read is used for a 32-bit SLIH, a pdiag_dd_read_64 will be used for a 64-bit SLIH. This will be accomplished by using conditional preprocessor compiler statements (#ifdef).

    Here is an example of what a common source 32-bit and 64-bit read call might look like:

    #ifdef __64BIT_KERNEL
         rc = pdiag_dd_read_64(pdiagex_handle, IOSHORT16, io_addr, &datas,
    &flags);
    #else
         rc = pdiag_dd_read(pdiagex_handle, IOSHORT16, io_addr, &datas,
    &flags);
    #endif
    Notes:
    1. The __64BIT_KERNEL compiler directive is defined for 64-bit kernel compilers, therefore the user will not need to define it.
    2. Special case for IOLONG32 reads, the data has to be shifted 32-bits right after the function call, such as, (data = data >> 32;).
    3. The pdiag_dd_read_64 function is used in kernel environment only, therefore the intrlev flag must always be set to INTRKMEM.
  2. Performing Write Operations to a Device

    All instances of pdiag_dd_write have to be duplicated with pdiag_dd_write_64 for 64-bit. Every place where pdiag_dd_write is used for a 32-bit SLIH, a pdiag_dd_write_64 will be used for a 64-bit SLIH. This will be accomplished by using conditional preprocessor compiler statements (#ifdef).

    Here is an example of what a common source 32-bit and 64-bit write call might look like:

    #ifdef __64BIT_KERNEL
            rc = pdiag_dd_write_64(pdiagex_handle, IOLONG32, io_addr,
    &datal, &flags);
    #else
            rc = pdiag_dd_write(pdiagex_handle, IOLONG32, io_addr, &datal,
    &flags);
    #endif
    Notes:
    1. The __64BIT_KERNEL compiler directive is defined for 64-bit kernel compilers, therefore the user will not need to define it.
    2. The pdiag_dd_read_64 function is used in kernel environment only, therefore the intrlev flag must always be set to INTRKMEM.
  3. SLIH function prototype

    The SLIH function prototype requires change in the type declaration for *sleep_word and sleep_flag as follows:

    int your_interrupt(pdiag_info_handle_t pdiagex_handle, char
    *data_area, int *interrupt_flag,
    #ifdef __64BIT_KERNEL
            long sleep_flag, long *sleep_word)
    #else
            int sleep_flag, int *sleep_word)
    #endif

Related Information

Diagnostic Components for general information on how to write interrupt handlers.

Interrupt Handler Call Interface

pdiag_dd_read, pdiag_dd_read_64 functions

pdiag_dd_write, pdiag_dd_write_64 functions

[ Top of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]