How to modify AMD APU vBIOS ?

been looking out for a while now what needs to be done in order to patch vbios of integrated graphics on bristol ridge APU (probably it would be valid for other APUs too)

vbios is part of system firmware, and as such it has some tables completely zeroed out. when system boots it detects hardware configuration, e.g. memory - DDR3-1600 or DDR4-2400 and updates the zeroed fields/tables from a vbios copy with this information and stores it at memory location 0xC0000 known as shadow vbios.

there is clover bootloader that has some sort of vbios load/patch option that should help just in case like ours, but it didn’t work.
grub loader has also loadbios option, but this one doesn’t work either. here i managed to find out why, while examining its code:

memory space at 0xC0000 is write-protected and grub’s loadbios code applies only to some old intel chipsets.

d3v1l at macrumors explained that quite well:

I need to shadow the VGA ROM manually at 0xC0000 and set the correct int10h value (firmware_version/logicboard_model specific hardcoded in the app). On NVidia Chipset Macs it works as the memory address is R/W. On Intel MCH style chipsets (pre Core i7) I also need to unlock the ram address by setting a value of 0x30, 0x33, 0x33, 0x33, 0x33, 0x33 on 90h-96h on the PCI Root Bridge since the address range is RO. On PCH style chipsets (core i5/i7) since the memory controller is in the CPU I need to unlock that RAM range using the fixed range MTRR.

i find equivalent in AMD BKDG, fixed MTRR whose memory type setting can be changed by writing to MSR 268 and 269, i try to read this MSR in linux it is 505050505050505 - means memory type is write-protect. since wrmsr in linux seems broken i added some code to amdmsrtweaker and recompiled it and with that tool i can set memory type of both MSR to write-back (or any other type)

but the thing is this needs to be done before linux or windows boots, and grub looks ideal for that, that’s when i ran into a problem: rdmsr command in grub shell cannot read the MSR 268, after trying to execute the command the shell is frozen and only thing that helps is power-cycle.
do i need to change some other MSR before getting any kind of access to MTRR MSR?

vbios structure is known, powerplay table also, i made a simple change like dropping highest GPU state’s voltage from 1.0875V to 1.0625V and fixed the checksum with AMDVBIOSChecksumTool

going back to linux and trying to read and write vbios directly from/to /dev/mem even after setting MTRR to write-back the modified vbios dump was not written to memory
however, if i try quick multiple writes to /dev/mem the modified dump gets written into memory (verified of course by dumping back the memory), interesting that this is possible even without changing MSR 268 and 269 memory type - obviously linux does it in it’s own hacky way
the only problem here is the gpu driver is already loaded and i didn’t figure out yet a way to reload it, or how to insert module after nomodeset boot - it spits out some error on the console…

maybe someone has another idea or two what else could help loading modified vbios?

just ran several valley benchmarks in linux with modified powerplay table: exact same scores and performance without any artifacts or glitches at GFX voltages first at default 1.0875V, then 1V and finally 0.94V. probably it could go below 0.9V
given that high power graphics that have almost twice of compute units comparing to integrated one, running at 150+ MHz higher frequency can still work fine at 0.9V, the only reason i can think of a BIOS engineer would bump low-power graphics to such an abnormal voltage level is to keep the APU/CPU warmer and more throttling… or he is just a plain dumbass