ThinkPad I9990303 Error Catch-22

I have an old, circa 1994 IBM ThinkPad 750C (with a 33MHz Intel 486SL processor) which used to work but now refuses to boot with error I9990303. The error prevents the laptop from booting normally and also prevents it from entering the BIOS setup program, which is fairly unusual—many other errors forcibly enter the BIOS setup.

It’s Not OK and RTFM!

Note “booting normally”. The ThinkPad can still boot from a specially marked floppy, such as IBM’s maintenance or BIOS update disks. From such a disk, it can boot to DOS, access the internal hard disk or PC Cards, or run Windows 3.1. In other words, there does not appear to be anything too wrong with the laptop.

However, the inability to run the BIOS setup prevents the laptop from being properly configured. This (presumably) also causes the PS2 utility to fail, among other things. So what does this error mean?

The IBM Hardware Maintenance Manual for the ThinkPad 750 says that error I9990303 indicates a faulty system board. It also contains this curious note: I9990303 errors can be caused by exposure to strong magnetic fields.

For newer ThinkPads (e.g. 760), error I9990303 is documented as “Bank–2 flash ROM check
sum error”. It is possible, even likely, that the error means the firmware is partially corrupted. If the run-time BIOS is fine but the ROM setup and diagnostics are corrupted, that would explain why this error prevents the BIOS setup from being entered.

The obvious fix would be to re-flash the BIOS. But… nope, that doesn’t work. The BIOS flash utility requires a charged battery, which I don’t have. However, it does not even get that far—it fails with an error message saying that The system power management is disabled. That is quite likely the same underlying problem as the one preventing the PS2 utility from working. In other words, the BIOS update does not even get as far as checking the battery state, it fails before getting to that point.

And there’s the Catch-22: A non-critical part of the BIOS flash storage is corrupted, which is something that re-flashing the BIOS would almost certainly fix. But the IBM BIOS update tool does not work because of the error caused by the flash being corrupted.

Get Me Out of Here

Is there a way around it? On some systems, there may be way to run the firmware update utility directly, without any checks. No such luck on the ThinkPad 750C: Although the update floppy is just a bootable DOS disk with a custom shell (COMMAND.COM replacement that directly runs the update utility), the UPDTFLSH.EXE tool has no obvious knobs to tweak.

The utility checks all the preconditions and performs the actual flashing. As far as I can tell, it takes no command-line arguments, does not look at any environment variables, and there is no apparent way to control its behavior.

The obvious solution is to modify the update utility to skip the checks. This is of course risky, the checks are there for a reason. Then again… have you ever flashed the BIOS on a desktop machine that didn’t have a sufficiently charged battery? Probably yes, and it worked just fine.

Old systems with BIOS in flash memory typically have no safety, no “boot block BIOS”, and if a BIOS update fails (e.g. due to power outage), the system will be bricked. That’s why laptops often insist on a charged battery, because it is a useful safety in case power is lost (the most likely cause of a failed BIOS update).

But I decided that since the laptop is already broken, trying to fix it is worth the risk. I disassembled the UPDTFLSH.EXE utility, and found it to be doing lots of poorly documented and entirely undocumented things. Luckily, the error messages gave me fairly good clues as to what the code was doing.

The ThinkPad 750C uses a 486SL processor and appears to use SMM (System Management Mode) to implement power management. It uses an interface that is (very) partially documented on Ralf Brown’s Interrupt List. UPDTFLSH.EXE calls INT 15h/5380h with BH=7Eh. This reportedly returns the “SL control port” in BX.

The utility then sets CH, CL, and BL to 49h, 42h, and 4Dh—the letters ‘I’, ‘B’, ‘M’ in ASCII.
AX is (again) set to 5380h and BH to F0h, and then the SL control port returned from the previous call is written via ‘OUT DX, AX’. This is presumably some kind of a presence check.

I am guessing this is the interface to the power management BIOS. It works much like a software interrupt, but it’s triggered by an I/O port write because the processing runs in SMM, in a separate address space.

If the OUT instruction does not set the carry flag (I said it works just like software interrupts!), the presence checks succeeded and the flash utility proceeds to issue further power management requests.

These check whether the ThinkPad is in an expansion unit (for some reason that’s a no-no for BIOS flashing, perhaps because then a power outage can’t be overcome by a battery), and there are other routines which check whether the laptop has a battery installed, and if the battery has enough charge.

As an aside, the ThinkPad 750C is technically a PS/2 machine, much like earlier IBM portables—although it does not use Microchannel like the ThinkPad 700/720 and older IBM laptops did. The model byte of the 750C is F8h (the submodel is 61h), which is a value used by all 32-bit PS/2 systems. It is not the same model byte (FCh) used by PC/AT compatibles, which was in fact also used by the ThinkPad 760 and later models. ISA based PS/2 models are not unheard of (e.g. Model 30), and there were other machines such as the PS/2 E (model 9533) which were 32-bit ISA based PS/2 systems.

But back the flash utility. I just decided to effectively patch out the entire routine at offset CC4h in the first code segment by always returning zero in AX, copy the hacked utility to the BIOS update disk, boot up the laptop and see what happens. The utility was EXEPACKed so it had to be unpacked and re-packed, but that’s boring.

The hacked up BIOS update utility did in fact avoid the power management related error and let me start the flash update process. I let it run, not at all sure what would happen.

It’s show time!

After the flashing was done, the laptop rebooted itself and greeted me with this familiar error screen:

The happy flapping duck

A success! The I9990303 error is gone, the BIOS setup can be entered, and the laptop boots normally again. The BIOS can configure everything, getting rid of errors 161 and 163 caused by the loss of CMOS contents. The PS2 utility also works again.

Summary

The I9990303 error on mid-1990s ThinkPads almost certainly indicates corrupted flash memory. EPROMs/flash don’t necessarily last forever and sometimes “forget” a bit here and there. This can usually be fixed by rewriting the contents; unfortunately in the case of the I9990303 error, the problem which would be fixed by flashing the BIOS actually prevents the BIOS from being flashed at all, which is almost certainly an unintentional side effect.

Using a hacked UPDTFLSH.EXE utility allows bypassing the check and flashing the BIOS. Successful flashing eliminates the I9990303 error.

This entry was posted in BIOS, IBM, Software Hacks, ThinkPad. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.