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
* Rudolf Marek r.marek@assembler.cz [080105 02:11]:
I'm pleased to announce that I got S3 working with LinuxBIOSv2 on ASUS A8V-E SE (K8 + VT8237 + K8T890)!
Rudolf,
this is wonderful! Thank you very much for your work!
- consolidate the memory usage of LinuxBIOSv2
What needs to be done here?
- dont clean arbitrary memory
This should at least be the case when waking up from S3.
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)
Sounds reasonable. How do others do this?
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.
Thank you.
Index: src/mainboard/asus/a8v-e_se/dsdt.asl
--- src/mainboard/asus/a8v-e_se/dsdt.asl (revision 2978) +++ src/mainboard/asus/a8v-e_se/dsdt.asl (working copy) @@ -44,6 +179,7 @@ */ Name (_S0, Package () {0x00, 0x00, 0x00, 0x00 }) Name (_S5, Package () {0x02, 0x02, 0x00, 0x00 })
Name (_S3, Package () {0x01, 0x01, 0x00, 0x00 })
/* Root of the bus hierarchy */ Scope (_SB)
How nice ACPI _can_ be :)
Index: src/mainboard/asus/a8v-e_se/wakeup.c
--- src/mainboard/asus/a8v-e_se/wakeup.c (revision 0) +++ src/mainboard/asus/a8v-e_se/wakeup.c (revision 0) @@ -0,0 +1,267 @@ +//reboot.c from linux
+#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <console/console.h>
[..]
A quick glimpse tells me that wakeup.c is mostly x86 generic code. We should put it somewhere else.
Stefan
Hi,
this is wonderful! Thank you very much for your work!
Yeah I'm happy that it works too. It costs me lot of time and I would rather win then lose ;) I'm taking this as broading up my know-how. It goes well because I got nearly all datasheets for all chips on the board except the marvel gigabit controller. I have in plan to add overclocking options, because I know how they work on this board - its on wiki now.
- consolidate the memory usage of LinuxBIOSv2
What needs to be done here?
Well I think secondary CPUS (APs) are started by some code (secondary.S) Which is loaded to some location.Plus for example all memory from 0K-1M is clean etc etc. For S3 we cant act "as an elephant in the pottery"
- dont clean arbitrary memory
This should at least be the case when waking up from S3.
Well we should just clean our heap, without the purge, resource management gets hoosed for some reason. We should not touch all the memory, only to defined regions.
We are missing the "reserved" memory infrastructure in LB. For the mmconfig and also for S3 we should pass via LB tables parts of memory which are reserved, and then build e820 based map on in in filo/grub.
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)
Sounds reasonable. How do others do this?
Award is reserving last 1MB of memory for its SMM/resume handler. LB is not relocatable, and ACPI specs says reserved memory can start at 8MB.
Or we can try to put all linuxbios and its heap to A0000-FFFFF if we want to support the S3. (we can switch on VGA when we are done with heap). My system has fairly lot of devices, so I need lot of heap memory. I can try to measure how much actually (I'm using 256K now). I dont know if 384KB is enough for all the code. Maybe we can just move everything to 1MB somewhere in system RAM, but question is if APs can be started on 1MB above (this needs to be checked)
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.
Thank you.
I will try to publish it in near future.
How nice ACPI _can_ be :)
Well some parts still missing and ACPI core in Linux is bit complaining:
sd 0:0:0:0: [sda] Stopping disk ACPI: PCI interrupt for device 0000:06:00.0 disabled sky2 eth0: disabling interface ACPI handle has no context! ACPI handle has no context! ACPI: PCI interrupt for device 0000:00:11.5 disabled ACPI handle has no context! ACPI: PCI interrupt for device 0000:00:10.4 disabled ACPI: PCI interrupt for device 0000:00:10.3 disabled ACPI: PCI interrupt for device 0000:00:10.2 disabled ACPI: PCI interrupt for device 0000:00:10.1 disabled ACPI: PCI interrupt for device 0000:00:10.0 disabled ACPI: PCI interrupt for device 0000:00:0f.1 disabled ACPI: PCI interrupt for device 0000:00:0f.0 disabled ACPI handle has no context! pci_set_power_state(): 0000:00:00.0: state=3, current state=5 Disabling non-boot CPUs ...
But it works fine. The difference between full off and S3 is just one Watt ;) so everything is shut off. For specific wakeups some ACPI AML code should be added. I'm waking up system with power button.
Index: src/mainboard/asus/a8v-e_se/wakeup.c
--- src/mainboard/asus/a8v-e_se/wakeup.c (revision 0) +++ src/mainboard/asus/a8v-e_se/wakeup.c (revision 0) @@ -0,0 +1,267 @@ +//reboot.c from linux
+#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <console/console.h>
[..]
A quick glimpse tells me that wakeup.c is mostly x86 generic code. We should put it somewhere else.
Yeah, that patch is quite experimental so I put it to that dir. Better layout of systems calls needs to be proposed/implemented.
Rudolf
On 06.01.2008 19:06, Rudolf Marek wrote:
Hi,
this is wonderful! Thank you very much for your work!
Yeah I'm happy that it works too. It costs me lot of time and I would rather win then lose ;) I'm taking this as broading up my know-how. It goes well because I got nearly all datasheets for all chips on the board except the marvel gigabit controller. I have in plan to add overclocking options, because I know how they work on this board - its on wiki now.
- consolidate the memory usage of LinuxBIOSv2
What needs to be done here?
Well I think secondary CPUS (APs) are started by some code (secondary.S) Which is loaded to some location.Plus for example all memory from 0K-1M is clean etc etc. For S3 we cant act "as an elephant in the pottery"
- dont clean arbitrary memory
This should at least be the case when waking up from S3.
Well we should just clean our heap, without the purge, resource management gets hoosed for some reason. We should not touch all the memory, only to defined regions.
We are missing the "reserved" memory infrastructure in LB. For the mmconfig and also for S3 we should pass via LB tables parts of memory which are reserved, and then build e820 based map on in in filo/grub.
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)
Sounds reasonable. How do others do this?
Award is reserving last 1MB of memory for its SMM/resume handler. LB is not relocatable, and ACPI specs says reserved memory can start at 8MB.
Or we can try to put all linuxbios and its heap to A0000-FFFFF if we want to support the S3. (we can switch on VGA when we are done with heap). My system has fairly lot of devices, so I need lot of heap memory. I can try to measure how much actually (I'm using 256K now). I dont know if 384KB is enough for all the code. Maybe we can just move everything to 1MB somewhere in system RAM, but question is if APs can be started on 1MB above (this needs to be checked)
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.
Thank you.
I will try to publish it in near future.
How nice ACPI _can_ be :)
Well some parts still missing and ACPI core in Linux is bit complaining:
sd 0:0:0:0: [sda] Stopping disk ACPI: PCI interrupt for device 0000:06:00.0 disabled sky2 eth0: disabling interface ACPI handle has no context! ACPI handle has no context! ACPI: PCI interrupt for device 0000:00:11.5 disabled ACPI handle has no context! ACPI: PCI interrupt for device 0000:00:10.4 disabled ACPI: PCI interrupt for device 0000:00:10.3 disabled ACPI: PCI interrupt for device 0000:00:10.2 disabled ACPI: PCI interrupt for device 0000:00:10.1 disabled ACPI: PCI interrupt for device 0000:00:10.0 disabled ACPI: PCI interrupt for device 0000:00:0f.1 disabled ACPI: PCI interrupt for device 0000:00:0f.0 disabled ACPI handle has no context! pci_set_power_state(): 0000:00:00.0: state=3, current state=5 Disabling non-boot CPUs ...
But it works fine. The difference between full off and S3 is just one Watt ;) so everything is shut off. For specific wakeups some ACPI AML code should be added. I'm waking up system with power button.
Index: src/mainboard/asus/a8v-e_se/wakeup.c
--- src/mainboard/asus/a8v-e_se/wakeup.c (revision 0) +++ src/mainboard/asus/a8v-e_se/wakeup.c (revision 0) @@ -0,0 +1,267 @@ +//reboot.c from linux
+#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <console/console.h>
[..]
A quick glimpse tells me that wakeup.c is mostly x86 generic code. We should put it somewhere else.
Yeah, that patch is quite experimental so I put it to that dir. Better layout of systems calls needs to be proposed/implemented.
With wakeup.c moved to a generic x86 location, the patch is Acked-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
We can't afford to lose that code.
Regards, Carl-Daniel
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi,
We can't afford to lose that code.
Well I think I can clean the code bit, maybe it can serve as good template for v3 (from the what needs to be done perspective) Cant promise that I will find time now, but I will try to schedule it bit -> or even better try with v3 once ACPI is there. Here is some quick hack to make it work:
Maybe we can get it working in v3?
Quick hacks:
1) detect the resume, write to sleep register "Full ON state" 2) memory needs to be exit from self refresh 3) when building the ACPI tables, record the waking vector 4) run full coreboot boot 5) instead of jumping to payload, go realmode, turn A20 and jump to waking vectror
6) run kernel with ro memmap=exactmap memmap=1018M@4M memmap=40k@896k ro just reserve tiny memory for Linux waking code, make sure that LB will not destroy this. rest of the memory can be clobbered by coreboot, (in this example all bellow 4MB)
Plus we need to have ACPI in v3 but I dont know if we do have.
Rudolf