SRC
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:
- Extract the segments.
QFILEMCDcontains SLIC as large memory segments stored at the addresses the link loader maps them to. - Build a name index. Two structures in the code give you addresses paired with names. Every compilation unit ends with a
TBTBtraceback trailer, many carrying the unit's name; and the link loader leaves a descriptor block per procedure, with the entry address at+0x08and the name in EBCDIC at+0x38. Merging both across every segment of a V4R4 image gives on the order of 184,000 named records. - 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.
- 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*SystemRefCodeconstructors 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
- System Files:QFILEMCD
- System Files:QFILEIML
- Data Structures:LID
- SRC 0000BBBB
- Disk device related system reference codes
- Tape device related system reference codes
- Panel Usage
Weblinks
- System reference code list, IBM Documentation
- AS/400e Service Functions, which documents the panel functions and the IPL progress code sequences