Feng, Libo wrote:
Hi, all,
Thank you very much. Such a lot of information pours to me. It will take quite a while for me to digest. ;-)
The below are my thought and some experiment results, the platform is: AMD dbm690t mainboard mounted with Turion 64x2, Rs690 and Sb600. OS is Fedora 6 shipping with the 2.6.18 kernel. ACPI spec is 3.0a
- According to the ACPI spec, prior to transitioning to S3, OS saves
a lot of processor and devices' context, flushes and invalids cache. Please reference to 15.1.6. I will check the kernel source to find what are exactly saved.
That is mostly correct. The OS is usually only responsible for "leaf" devices - meaning devices that are attached to a bus. In other words, the OS knows how to save the SATA controller, but it won't understand how to restore the southbridge so that it can see the SATA controller. During a suspend, most (but not all) of the chipsets will be powered down. A good rule of thumb is that if you have to configure a device in coreboot during cold boot, then you probably have to configure it during resume. When in doubt, check the kernel to see what it does. In the beginning, it probably wouldn't hurt if you accidentally set up a device twice, but we want to avoid that as much as possible.
- In 15.1.3.1, Only the four items below need to be done by BIOS
when waking up: 1. Program the initial boot configuration of the CPU (such as the MSR and MTRR registers). 2. Initialize the cache controller to its initial boot size and configuration. 3. Enable the memory controller to accept memory accesses. 4. Jump to the waking vector.
As I said above - you will probably have some chipset initialization that needs to happen.
- In coreboot, within cache_as_ram_auto.c, the cache is enabled. Not
all MTRR but some are set up, precisely, MSR 0269h MTRfix4K_C8000 Register and MSR 02FFh MTRRdefType Register. The memory controller is setup, too. So if we don’t copy the data in cache and the coreboot code into RAM in the function of post_cache_as_ram, the content of RAM keeps intact since the last transition of S3.
- Then, is RAM accessible in cache_as_ram_auto.c now? I did some
experiments. FACS table can be found, the waking vector can be fetched. With HDT( AMD debug tool ), I can also find the waking source code at 0x2000 in RAM, identical with /arch/x86_64/kernel/acpi/wakeup.S. So, I think after initializing the memory controller, RAM has exited the self-refresh state.
- At this point, Power Management Register is also accessible,
strange but true. So I can decide it is normal boot or waking by reading Sleep Type in AcpiPm1CntBlk.
Above, I said that not all the chipset is turned off during suspend - this is one of those registers that lives in what we call the standby domain. The standby domain saves the state of the registers through a suspend especially so that you can read it at this point.
- Some MSR and MTRR can be stored in CMOS RAM during the previous
normal boot, now I can read back them from CMOS RAM.
This is not a good idea - you have limited CMOS space, and you will quickly fill it up. It is perfectly valid to save the values of these registers in a reserved bit of system memory. When you resume, bring up the memory with default MSR and MTRR values (like on cold boot), and then restore the active values after you can access RAM. I think that you will find that most of the MSR values are the "default" values set at cold boot time, so you probably don't need to save many of those.
You will need some system RAM to save state and to have a stack - you can reserve that memory at boot time through the coreboot tables, and then use it at will during resume.
- After all these, jumping to the waking vector and handing the
control to OS, OS will restore system and wake up.
Don't forget to put the code into 16 bit mode before jumping to the wake vector.
Jordan