SRC

From Try-AS/400
Jump to navigation Jump to search

A system reference code (SRC) is the AS/400's primary way of telling you what it is doing or what went wrong. It is the string of hexadecimal characters shown on the operator panel's display, and the same codes appear in the system's logs and on the console. Because the platform is designed to be serviced by someone who may not have a working console, the SRC is deliberately the lowest-common-denominator channel: it works when nothing else does.

This article covers what an SRC is and, more usefully, how to work back from one to the piece of Licensed Internal Code that produced it. Individual codes are catalogued elsewhere — see Disk device related system reference codes, Tape device related system reference codes and SRC 0000BBBB for worked cases.

What an SRC looks like

The panel displays eight hexadecimal characters. That display is only the first of several words the machine has available; the remainder are reached with the panel's extended functions, and all of them are recorded in the logs.

The leading character is the most informative part, because it identifies what kind of event you are looking at:

Leading character Meaning
A Attended IPL — the machine is waiting for you
B A problem was detected, most often by Licensed Internal Code
C IPL progress; the machine is working normally
D Power-down progress

The distinction that matters when something appears stuck is between C and B. A C code is a progress report, and a machine sitting on one for a long time may simply be doing something slow. A B code is a failure, and it will not clear itself.

Progress codes are genuinely informative about sequence. The IPL-time verification sequence, for instance, runs:

SRC Meaning
C600 4500 Verifying network attributes
C600 4504 Verifying system serial number
C600 4505 Verifying system type
C600 4506 Verifying system-unique ID
C600 4507 Starting 'before DST' DASD checker
C600 4508 Verifying system password
C600 450A Starting 'after DST' DASD checker

Read as a whole, that tells you the order of dependency inside the IPL — serial number, then type, then unique ID, then disk state, then the system password — which is information you will not find stated anywhere as prose. Progress codes are a free execution trace of the boot path, and reading a long capture of them is a cheap way to understand a sequence you cannot otherwise observe.

Where SRCs are recorded

The panel shows the current one. Everything else is in the machine:

  • Panel extended functions step through the additional words of the current SRC.
  • The Product Activity Log, under DST or SST, holds hardware-detected events with their full word set and timestamps.
  • The Licensed Internal Code log holds LIC-detected events. This is the one that matters for the technique below, because for a LIC-detected error it records the failing module — not just a code.
  • Main storage dumps capture machine state at the point of failure.

If you are trying to understand a failure rather than merely clear it, go to the logs. The panel gives you one word of what may be a nine-word record.

How SRCs are produced

Inside SLIC there is a family of classes that construct reference codes, one per flavour of event:

IoMFSystemRefCode                 base
IoMFGenericSystemRefCode          generic
IoMFAttentionSystemRefCode        attention
IoMFIplStatusSystemRefCode        IPL status
IoMFRunStatusSystemRefCode        run-time status
IoMFTerminalSystemRefCode         terminal
IoMFExtendedSrc / IoMFExtendedSrcHyp

alongside a set of categories that amount to the machine's error taxonomy — IoMFSrcDeviceFailure, IoMFSrcIoError, IoMFSrcIopCodeDetectedFailure, IoMFSrcSlicDetectedError, IoMFSrcIopFailureNoDeviceVpd and several more. Persistent logging goes through an entry point named putSrc on the persistent-machine class.

Getting the code onto the panel is a separate step, handled by a request/acknowledge message protocol to the service processor. The panel-related messages include IoMFCEMessageSRCDisplay to display a code and IoMFCEMessagePNLClearSRC to clear it, in among messages for panel button notifications, power control and IPL mode. The panel is a small subassembly with its own microcontroller, driven over what appears from the software side to be a simple serial link.

The practical consequence is that posting an SRC is an ordinary function call made from ordinary code. It is not a hardware trap or a magic register. So the code that posted a given SRC is findable by the same means as any other caller.

Working back from an SRC to a LIC module

This is the part worth generalising, because the same route serves any question of the form "which code did this?" — not only SRCs.

On the machine

For a LIC-detected error, the Licensed Internal Code log entry names the failing module directly. That is the short path and should always be tried first: DST or SST, the LIC log, then the detailed display for the entry in question. You are looking for a module name and an offset within it.

Module names follow visible conventions once you have seen a few. Names beginning with # are SLIC-internal modules; the rest are C++ symbols and are mangled, so a name like putSrc__16NuPersistMachineFUtPv decomposes into a method putSrc on class NuPersistMachine taking an unsigned halfword and a pointer.

Offline, from installation media

When the log does not name a module, or when you want to read the code rather than just identify it, the route runs through System Files:QFILEMCD:

  1. Extract the segments. QFILEMCD contains SLIC as large memory segments stored at the addresses the link loader maps them to.
  2. Build a name index. Two structures in the code give you addresses paired with names. Every compilation unit ends with a TBTB traceback trailer, many carrying the unit's name; and the link loader leaves a descriptor block per procedure, with the entry address at +0x08 and the name in EBCDIC at +0x38. Merging both across every segment of a V4R4 image gives on the order of 184,000 named records.
  3. Look the address up. Prefer descriptor hits, which name exactly one procedure, over traceback hits, which cover a whole compilation unit and so only tell you which module an address is in.
  4. Find who posts the code. Because SRC posting is a normal call, you can find every site that posts one by resolving the calls to the IoMF*SystemRefCode constructors and reading what the caller places in the code fields just beforehand.

Step 4 needs one piece of SLIC-specific knowledge. External calls do not go through a dispatch table you can read off. A call is ori r11,r13,ordinal followed by bla into a transfer vector at the top of the address space, and the 16-byte stub it lands on computes the target arithmetically from the ordinal. To resolve calls you need the stub constants, which are not derivable and must be read from a dump of the transfer vector segment. With them, every external call in a segment resolves mechanically.

A worked example

The DST module that verifies the system password illustrates the whole path. Immediately before it calls IoMFGenericSystemRefCode, it does this:

li    r0,  0x12                  ; 18
li    r31, 0x21                  ; 33
lhz   r6,  0x18(r29)             ; the password status halfword
cmpwi r6,  0x30
bne   ...
sth   r0,  0x44(r1)              ; status == 0x30 -> code 0x12
b     ...
sth   r31, 0x44(r1)              ; otherwise      -> code 0x21
ori   r11, r13, 0xd45c
bla   ...                        ; IoMFGenericSystemRefCode

Read backwards, this is exactly the inference you want to be able to make. The reference code is chosen from a status halfword; a status of 0x30 produces one code and anything else produces another. So the two codes are not two unrelated faults but two branches of one test, and knowing which one appeared tells you which branch was taken. Working forward from the SRC list would never reveal that relationship.

What the method will not give you

Two honest limits. A traceback trailer names a compilation unit, which may contain many entry points, so it localises rather than pinpoints. And addresses are per-build, not per-release: the same class sits at a completely different address on a machine of another build, so a name index is only valid against the media it was built from. Always match your extracted image to the machine you are investigating, using the build label carried in both container files.

Why this is worth learning

The technique generalises well beyond diagnosing faults. An SRC sequence is an execution trace with names attached, and the machine emits one on every IPL whether or not anything is wrong. Combined with a name index over the LIC image, it lets you ask questions the documentation does not answer — what the machine checks and in what order, which subsystem owns a given behaviour, where a slow phase is actually spending its time — using only a panel display and a copy of the installation media.

See also

Weblinks

Footnotes