aytugyayman

DDR5 · APOB

Reading tCCD_L from APOB

Aytug Yayman 2 min read

Adding DDR5 timings exposed a problem: tCCD_L, tCCD_L_WR and tCCD_L_WR2 did not all come from the same source. Showing the running configuration required checking what each value actually represented.

Starting with the memory controller

ZenStates-Core did not read the full family at the time. I found register counterparts for tCCD_L and tCCD_L_WR2, but not for tCCD_L_WR. Rather than estimate the missing field from the other two, I looked for another source.

SPD and running timings must be kept separate. SPD describes module identity and profiles; it does not by itself prove which settings the memory controller uses after BIOS training.

The APOB data left by the BIOS

The missing field appeared in the APOB data the BIOS leaves in memory during startup. A position found on one motherboard was not a universal offset: the board and AGESA version can change the layout. From fork version v1.42.6, all three fields are read through APOB.

The table header, block boundaries, value width and plausible ranges need to be considered together. An APOB heading in a report does not prove that its data was decoded successfully. Main and extended blocks also need separate availability checks.

Checking a reading

Before-and-after debug reports from the same machine are useful evidence. Changing one BIOS timing makes it possible to track the corresponding field, instead of treating a coincidental number as a timing. Existing register readings offer an additional consistency check.

For a wrong reading on a new BIOS, I ask for the CPU, motherboard, BIOS and AGESA versions together with both reports. Re-parsing saved reports reduces the need to access hardware for every fix. Correct results on a few machines do not validate every DDR5 platform.

Sources and related work

All articles