Hi all,
I'm pleased to announce that I got S3 working with LinuxBIOSv2 on ASUS A8V-E SE (K8 + VT8237 + K8T890)!
I'm attaching the patch which is a big mess, but perhaps all are curious how is it done.
To be able to do S3 we must first set the register values used for sleep in ACPI DSDT table:
+ Name (_S3, Package () {0x01, 0x01, 0x00, 0x00 })
Plus we need some callbacks to SB code which tells LinuxBIOS if it is normal startup or Wakeup and if it is a wakeup we need to know the vector to return to OS. This vector is stored in one ACPI table and because LinuxBIOSv2 puts tables on same place I will take the vector value just before I overwrite it ;)
So how it works?
LinuxBIOS will boot as usual if S3, but not executing payload but jumping to real mode waking vector from OS. During memory initialization we need to exit the self-refresh mode instead of training the memory again. Plus we need to adjust the K8 registers to listen for SMAF messages from SB that we go S3.
The serious problem is that LinuxBIOS overwrites a lot of memory - lowmem, highmem (1M above). So how to protect it for OS?
I booted linux with custom memory map 2M-1GB and LinuxBIOS had 0M-2M for its own stuff. But If I reserved memory for linux this way, ACPI code refuses to work, because OS waking code must be in 1MB range. I decided to patch the kernel and put always waking code to 0xE000:0000
/linux-2.6.23.1/arch/x86_64/kernel/acpi/sleep.c
void __init acpi_reserve_bootmem(void) { acpi_wakeup_address = phys_to_virt(0xE0000); //(unsigned long)alloc_bootmem_low(PAGE_SIZE*2); printk("ACpi wakeup %x\n", acpi_wakeup_address); if ((&wakeup_end - &wakeup_start) > (PAGE_SIZE*2)) printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt" " to suspend\n"); }
Getting close to have working implementation but one thing was still missing. The exit from Self refresh seemed not to work. But, booting with original BIOS, rebooting to LB and then suspend/resume in LB did work! Hum something was wrong with some chip, but not with memory itself. Today I found out. There seems to be some undocumented bit in Winbond W83627EHF which will leave power to right parts of the system :) The attached script fix_ehf has a workaround ;)
In the meanwhile I found out how to blink with the power LED and how to overclock the motherboard + most GPIO meaning, so I updated the Wiki page with that too.
So what needs to be done?
1) consolidate the memory usage of LinuxBIOSv2 2) dont clean arbitrary memory
Perhaps we could reserve last 1MB of RAM or something after 8MB of mem and put linuxBIOS heap there when using S3 we would just reserve the region + (some region bellow the 1MB for AP CPU boot + ACPI tables etc)
The patch has some errata update of code too, I will publish this as separate patch - I did it because I thought I got still some memory related problem.
Unfortunately I do not have much time for this fun, very busy with other stuff, but I needed some break ;)
Oh I forgot - the real mode switcher and A20 handler are from Linux kernel.
Thanks,
Rudolf
isaset -y -f 0x2e 0x87 isaset -y -f 0x2e 0x87 isaset -y 0x2e 0x2f 0x7 0xa isaset -y 0x2e 0x2f 0xe6 0x10 isaset -y 0x2e 0x2f 0xe4 0x30 isadump -y -k 0x87,0x87 0x2e 0x2f 0xa