So after a few days the code seemed to work quite fine with multiple DIMMs in different combinations. Time to upstream! Doing native raminit on x86 (in coreboot) is quite a lost art. One of the people enjoying this dark magic is Angel Pons. So I asked him if he would kindly review this code (he's a very thorough reviewer). To my eyes the code looked 'aight, but he has way better eyesight than mine at least with regard to code.
Here is a summary of what went wrong:
First of all the code sometimes just didn't know what hardware it was talking to.
Some register names were copied from nearby chipsets, some came from decompiler vibes and some were just wrong.
Angel pointed out a few cases where the datasheet really did say something else: wrong register names, reserved bits treated as real bits, wrong access sizes.
One good example was the GM965 0xa00 MCHBAR range.
The code initially had some hallucinated register block semantics. A closer look revealed it is much closer to the EP channel / ME stuff seen on other Intel chipsets.
The raminit also had actual bugs. Some timing tables were indexed the wrong way around, some bitfields had the wrong meaning and some calculations only worked by luck for the DIMMs I tested. Peak 'works on my machine' problems. This happened in quite a few other places: tons of code assuming thinkpad x61 in the southbridge:
- hardcoded init bits
- hardcoded device enable/disable that just fit the x61.
So thanks to Angel to help transforming this bring up hack into upstreamable chipset code.
The worst/most frustrating part of the review process had nothing to do with LLMs. It came from clangfmt. Both the LLM agent as well as Emacs were set up to use this by default. The results of this tool are not good to say the least in the coreboot codebase. I was fighting this tool more than it gave me benefits and so in frustration I sent a patch to just rip out the clang-format config out of coreboot.
So vibe reverse engineering won't be upstreamable without a real engineer anytime soon.