Discussing on IRC, ruik pointed out that we of course have to consider suspend and resume in v3.
He wrote some great pointers on the topic today and I'm pasting here for archival and as food for thought.
<ruik> CareBear: the S3 works this way: <ruik> 1) get the wakeup info from chipset <ruik> 2) in intraphase ask the memory to go out of self refresh (skip train) <ruik> 3) do coreboot chipset init as usual <ruik> 4) when creating ACPI tables look to that place, in one table there will be OS waking vector <ruik> 5) after all done, jump to OS instead of payload, switch A20 on go to real mode and jump <ruik> 6) do this all steps in reserved memory, do not corrupt system memory used by OS <ruik> 7) minor fix for ACPI dsdt is needed, just one line ;) <ruik> CareBear: just add one line to SLP <ruik> similar to bit for S5 and S0 <ruik> one more caveat <ruik> make sure that suspend signal clock from SB is understood by superIO <ruik> so superIO wont cut RAM power
I think 6) in particular deserves some consideration.
//Peter
great info.
I'd never considered any of this, which shows my cluster bias :-)
OK where do we want v3 reserved memory?
ron
I'd never considered any of this, which shows my cluster bias :-)
OK where do we want v3 reserved memory?
I think we can reserve last MB of RAM, where we will copy coreboot and stacks/heaps. If anyone is worried about the "waste" of last MB. I think we can hotplug the memory back to OS through ACPI, got some experimental ASL code, but kernel panicked. Maybe it is there some glitch.
The tables might not be written for second time, when resuming because they are there already ;)
The code absolutely _must_ _not_ write to any other memory. No strange AP stacks in random 0 - 640kb ;)
There is no need for SMM code.
Here is mine v2 suspend/resume http://www.coreboot.org/pipermail/coreboot/2008-January/028787.html
Rudolf
Rudolf Marek wrote:
OK where do we want v3 reserved memory?
I think we can reserve last MB of RAM, where we will copy coreboot and stacks/heaps.
I would ideally like to use the correct location all the time so that we don't have to copy.
Is it doable to determine coreboot RAM location at runtime?
If anyone is worried about the "waste" of last MB. I think we can hotplug the memory back to OS through ACPI, got some experimental ASL code, but kernel panicked. Maybe it is there some glitch.
Then we can't suspend again. Seems problematic. Those who enable suspend/resume in our Kconfig will simply have to pay the cost of some RAM.
The code absolutely _must_ _not_ write to any other memory. No strange AP stacks in random 0 - 640kb ;)
Right, this is my concern.
//Peter
Is it doable to determine coreboot RAM location at runtime?
Hmm I dont know how v3 works. But ACPI assumes that there must be 8MB from the 1MB continuous, so maybe we can even do a hole after 8MB ;) (and call it ACPI NVS, for example).
If anyone is worried about the "waste" of last MB. I think we can hotplug the memory back to OS through ACPI, got some experimental ASL code, but kernel panicked. Maybe it is there some glitch.
Then we can't suspend again. Seems problematic. Those who enable suspend/resume in our Kconfig will simply have to pay the cost of some RAM.
If the linux hotplug succeeds to free the memory again then it should work. But I agree, ACPI is telling that there might be holes after first 8MB, so maybe we can put coreboot to any addr bigger then 8MB.
The code absolutely _must_ _not_ write to any other memory. No strange AP stacks in random 0 - 640kb ;)
Right, this is my concern.
Yep cool.
Rudolf
Hi,
On Sun, Sep 07, 2008 at 10:44:11PM +0200, Rudolf Marek wrote:
Is it doable to determine coreboot RAM location at runtime?
Hmm I dont know how v3 works. But ACPI assumes that there must be 8MB from the 1MB continuous, so maybe we can even do a hole after 8MB ;) (and call it ACPI NVS, for example).
That wont work. I read some spec that demanded continuous ram from 0-16MB, and I thus inferred that I could put a hole after 16MB. Unfortunately after I did this, I found that it broke some linux installers. I believe they had a large initrd which consumed more than the first 16MB of ram.
Putting the hole at the end of ram definitely works though.
-Kevin
Kevin O'Connor wrote:
Hi,
On Sun, Sep 07, 2008 at 10:44:11PM +0200, Rudolf Marek wrote:
Is it doable to determine coreboot RAM location at runtime?
Hmm I dont know how v3 works. But ACPI assumes that there must be 8MB from the 1MB continuous, so maybe we can even do a hole after 8MB ;) (and call it ACPI NVS, for example).
That wont work. I read some spec that demanded continuous ram from 0-16MB, and I thus inferred that I could put a hole after 16MB. Unfortunately after I did this, I found that it broke some linux installers. I believe they had a large initrd which consumed more than the first 16MB of ram.
Putting the hole at the end of ram definitely works though.
Yes, it also makes most sense. This way the memory is not fragmented.
Rudolf, thanks for giving us that overview. I see that it is a description of S3 wakeup. Could you perhaps supplement that with a description of S3 suspend?
Peter, thanks for preserving that info.
On 07.09.2008 19:50, Peter Stuge wrote:
Discussing on IRC, ruik pointed out that we of course have to consider suspend and resume in v3.
He wrote some great pointers on the topic today and I'm pasting here for archival and as food for thought.
<ruik> CareBear: the S3 works this way: <ruik> 1) get the wakeup info from chipset <ruik> 2) in intraphase ask the memory to go out of self refresh (skip train)
intraphase is initram? Would it make sense to have a fast path in initram for this?
<ruik> 3) do coreboot chipset init as usual
What about BARs which have been moved by the OS? Should we initialize them to the values last used by the OS or should we use the values calculated automatically at startup?
<ruik> 4) when creating ACPI tables look to that place, in one table there will be OS waking vector <ruik> 5) after all done, jump to OS instead of payload, switch A20 on go to real mode and jump <ruik> 6) do this all steps in reserved memory, do not corrupt system memory used by OS <ruik> 7) minor fix for ACPI dsdt is needed, just one line ;) <ruik> CareBear: just add one line to SLP <ruik> similar to bit for S5 and S0 <ruik> one more caveat <ruik> make sure that suspend signal clock from SB is understood by superIO <ruik> so superIO wont cut RAM power
I think 6) in particular deserves some consideration.
6) is really easy with v3. A lot easier than with v2. I think I wrote a design doc about that one year ago.
However, I am surprised that the SuperI/O acts as a power supply for RAM.
Regards, Carl-Daniel
Carl-Daniel Hailfinger napsal(a):
Rudolf, thanks for giving us that overview. I see that it is a description of S3 wakeup. Could you perhaps supplement that with a description of S3 suspend?
S3 suspend is just this line in ACPI ASL:
+Name (_S3, Package () {0x01, 0x01, 0x00, 0x00 })
OS will write the 0x1 to SLP register in ACPI PMIO. OS will take care of cache flushes etc. The write to this register will cause the SMAF Stop grant message to be send to CPU, CPU will disconnect the bus, and SB will sequence all signals similar to power off. The only problem is suspend signal which goes to superIO, which is needed not to cut power to RAM.
In other words, you dont need to preserve anything/no need for SMM. ACPI allows that the hardware is in same state as it was during normal power on (for HW managed by BIOS).
If needed, writing to SLP register might be traped by SMM, and BIOS can save some values to NVRAM regs, sometimes found in chipsets (memory timing etc) to ease the startup. But we dont need that we are fast anyway.
Some extra hw clobber might be done in ACPI ASL code, there are methods which will be called during wakeup or during resume.
Rudolf
On 07.09.2008 21:28, Rudolf Marek wrote:
Carl-Daniel Hailfinger napsal(a):
Rudolf, thanks for giving us that overview. I see that it is a description of S3 wakeup. Could you perhaps supplement that with a description of S3 suspend?
S3 suspend is just this line in ACPI ASL:
+Name (_S3, Package () {0x01, 0x01, 0x00, 0x00 })
OS will write the 0x1 to SLP register in ACPI PMIO. OS will take care of cache flushes etc. The write to this register will cause the SMAF Stop grant message to be send to CPU, CPU will disconnect the bus, and SB will sequence all signals similar to power off. The only problem is suspend signal which goes to superIO, which is needed not to cut power to RAM.
In other words, you dont need to preserve anything/no need for SMM. ACPI allows that the hardware is in same state as it was during normal power on (for HW managed by BIOS).
CAR will write to memory locations below 1M. There are three ways to cope with that: 1. Back up that area during suspend and restore it as last instruction of resume. 2. Declare the CAR area (48 kB) as reserved memory. 3. Write excessively clever and fragile code which performs a double stack switch during resume. Evaluation: 1. Needs a SMM handler or some other way to trigger execution of the backup routine on suspend. 2. Reduces the amount of available low memory a bit, may be a problem for 16-bit operating systems like DOS. 3. Will NOT work for Geode, may not work for Intel and VIA. The existing CAR enabling/disabling code will seem trivial in comparison.
If needed, writing to SLP register might be traped by SMM, and BIOS can save some values to NVRAM regs, sometimes found in chipsets (memory timing etc) to ease the startup. But we dont need that we are fast anyway.
Some extra hw clobber might be done in ACPI ASL code, there are methods which will be called during wakeup or during resume.
In theory, the ASL could contain a memory backup routine as suspend preparation, but this would probably impractical.
Regards, Carl-Daniel
CAR will write to memory locations below 1M. There are three ways to cope with that:
- Back up that area during suspend and restore it as last instruction
of resume. 2. Declare the CAR area (48 kB) as reserved memory.
Imho this is OK, and easiest.
- Write excessively clever and fragile code which performs a double
stack switch during resume.
Here are some other ideas, might not work if stack is never realocated. I dont know how CAR in v3 works.
4. use 0xA0000-0xBFFFF
I think we can use this RAM because it will be covered by SMM (done by us) or will be covered by legacy VGA anyway.
5. use 0xf0000-0xfffff
It will get overwritten by some our code, before that we might use it.
Rudolf
On 07.09.2008 23:40, Rudolf Marek wrote:
CAR will write to memory locations below 1M. There are three ways to cope with that:
- Back up that area during suspend and restore it as last instruction
of resume. 2. Declare the CAR area (48 kB) as reserved memory.
Imho this is OK, and easiest.
Fine. Let's take that route.
- Write excessively clever and fragile code which performs a double
stack switch during resume.
Here are some other ideas, might not work if stack is never realocated. I dont know how CAR in v3 works.
All targets in v3 don't move the stack. That allows us to store data structures with globally valid pointers on the stack and it a
- use 0xA0000-0xBFFFF
I think we can use this RAM because it will be covered by SMM (done by us) or will be covered by legacy VGA anyway.
That would cause a collision if coreboot runs the VGA ROM. I might be wrong about that, though.
- use 0xf0000-0xfffff
It will get overwritten by some our code, before that we might use it.
I have to recheck this, but it might be possible that this location is not available for CAR on every processor.
Thanks for your insights.
Regards, Carl-Daniel
Hi,
On Sun, Sep 07, 2008 at 11:40:51PM +0200, Rudolf Marek wrote:
CAR will write to memory locations below 1M. There are three ways to cope with that:
- Back up that area during suspend and restore it as last instruction
of resume. 2. Declare the CAR area (48 kB) as reserved memory.
Imho this is OK, and easiest.
I don't think one can mark 48KB reserved below 0xA0000. I've found that boot loaders are picky about any reserved memory below 1MB.
It's normal to reserve the ebda (typically 0x9fc00 to 0xa0000), but I seem to recall reading that an EBDA over 16KB will confuse some programs. Using the EBDA area would also likely break SeaBIOS.
- Write excessively clever and fragile code which performs a double
stack switch during resume.
Here are some other ideas, might not work if stack is never realocated. I dont know how CAR in v3 works.
- use 0xA0000-0xBFFFF
I think we can use this RAM because it will be covered by SMM (done by us) or will be covered by legacy VGA anyway.
That should work for CAR, but it obviously wouldn't be useful for any long term storage.
- use 0xf0000-0xfffff
It will get overwritten by some our code, before that we might use it.
Using that area would prevent SeaBIOS from working.
-Kevin
On 08.09.2008 01:27, Kevin O'Connor wrote:
Hi,
On Sun, Sep 07, 2008 at 11:40:51PM +0200, Rudolf Marek wrote:
CAR will write to memory locations below 1M. There are three ways to cope with that:
- Back up that area during suspend and restore it as last instruction
of resume. 2. Declare the CAR area (48 kB) as reserved memory.
Imho this is OK, and easiest.
I don't think one can mark 48KB reserved below 0xA0000. I've found that boot loaders are picky about any reserved memory below 1MB.
Would 0xC0000-0xCFFFF for be OK? We already use that on some targets.
It's normal to reserve the ebda (typically 0x9fc00 to 0xa0000), but I seem to recall reading that an EBDA over 16KB will confuse some programs. Using the EBDA area would also likely break SeaBIOS.
We don't want to break SeaBIOS. Having an EBDA area might be useful sometime in the future, though.
- Write excessively clever and fragile code which performs a double
stack switch during resume.
Here are some other ideas, might not work if stack is never realocated. I dont know how CAR in v3 works.
- use 0xA0000-0xBFFFF
I think we can use this RAM because it will be covered by SMM (done by us) or will be covered by legacy VGA anyway.
That should work for CAR, but it obviously wouldn't be useful for any long term storage.
The CAR area in v3 is where the stack lives during CAR and after RAMinit. So if any code/hardware clobbers it before the last instruction of coreboot, v3 will explode. The v2 model of having 2 stack locations was a source of lots of headaches.
- use 0xf0000-0xfffff
It will get overwritten by some our code, before that we might use it.
Using that area would prevent SeaBIOS from working.
OK, so the 0xC0000-0xCFFFF area is likely our only option, then.
Regards, Carl-Daniel
On Mon, Sep 08, 2008 at 01:50:07AM +0200, Carl-Daniel Hailfinger wrote:
On 08.09.2008 01:27, Kevin O'Connor wrote:
I don't think one can mark 48KB reserved below 0xA0000. I've found that boot loaders are picky about any reserved memory below 1MB.
Would 0xC0000-0xCFFFF for be OK? We already use that on some targets.
Using the space at 0xc8000 - 0xf0000 would work, but it would limit the maximum number of option roms. (You can't use 0xc0000 for long term storage, because the vga option rom must reside there.)
-Kevin
On 08.09.2008 02:20, Kevin O'Connor wrote:
On Mon, Sep 08, 2008 at 01:50:07AM +0200, Carl-Daniel Hailfinger wrote:
On 08.09.2008 01:27, Kevin O'Connor wrote:
I don't think one can mark 48KB reserved below 0xA0000. I've found that boot loaders are picky about any reserved memory below 1MB.
Would 0xC0000-0xCFFFF for be OK? We already use that on some targets.
Using the space at 0xc8000 - 0xf0000 would work, but it would limit the maximum number of option roms.
That applies to any location between 0xA0000 and 0xFFFFF, though. And a location below 0xA0000 would cause collisions with operating systems and bootloaders requiring lowmem if we didn't discard the stack after finishing execution of coreboot.
(You can't use 0xc0000 for long term storage, because the vga option rom must reside there.)
Fortunately, the stack is designed to be discarded the moment we run a payload, so there are no survival requirements at all.
Regards, Carl-Daniel
On Mon, Sep 08, 2008 at 02:33:01AM +0200, Carl-Daniel Hailfinger wrote:
On 08.09.2008 02:20, Kevin O'Connor wrote:
Using the space at 0xc8000 - 0xf0000 would work, but it would limit the maximum number of option roms.
That applies to any location between 0xA0000 and 0xFFFFF, though.
Option roms reside between 0xc0000 and 0xf0000. The a and b segments are used for something else - vga mmio I think.
(You can't use 0xc0000 for long term storage, because the vga option rom must reside there.)
Fortunately, the stack is designed to be discarded the moment we run a payload, so there are no survival requirements at all.
On resume though, the CAR area would overwrite the VGA rom that was installed during the first boot.
Any memory that coreboot might clobber would need to be reserved, and 0xc0000 can't be reserved because vga option roms expect to be located there.
An alternative (as you mentioned in an early email) would be to save and restore some area of memory below 1MB.
-Kevin
On 08.09.2008 03:37, Kevin O'Connor wrote:
On Mon, Sep 08, 2008 at 02:33:01AM +0200, Carl-Daniel Hailfinger wrote:
On 08.09.2008 02:20, Kevin O'Connor wrote:
Using the space at 0xc8000 - 0xf0000 would work, but it would limit the maximum number of option roms.
That applies to any location between 0xA0000 and 0xFFFFF, though.
Option roms reside between 0xc0000 and 0xf0000. The a and b segments are used for something else - vga mmio I think.
Thanks for clearing up that misconception.
(You can't use 0xc0000 for long term storage, because the vga option rom must reside there.)
Fortunately, the stack is designed to be discarded the moment we run a payload, so there are no survival requirements at all.
On resume though, the CAR area would overwrite the VGA rom that was installed during the first boot.
That's bad.
Any memory that coreboot might clobber would need to be reserved, and 0xc0000 can't be reserved because vga option roms expect to be located there.
OK. The problem here is that large multicore machines need 48 kB CAR size, probably more in the future. Are VGA option ROMs guaranteed to be 16 kB or smaller? IIRC my laptop has a 36 kB VGA option ROM, but it's been a long time since I touched that.
An alternative (as you mentioned in an early email) would be to save and restore some area of memory below 1MB.
Yes, but the problem is that the CAR area can't be saved before enabling CAR. That means we have to reserve the memory. Let me summarize the current black list: - 0x00000-0x9FFFF is low 640 kB. May break bootloaders and 16-bit OS. - 0xA0000-0xAFFFF is VGA graphics memory mapped area. - 0xB0000-0xB7FFF is ancient monochrome memmapped, but may still be decoded by newer VGA cards. - 0xB8000-0xBFFFF is VGA text mode memory mapped area. - 0xC0000-???? is VGA ROM location. - 0xF0000-0xFFFFF is used by SeaBIOS.
IMO, the first choice would be 0xC4000-0xCFFFF (if VGA ROMs are 16 kB or smaller). 0xE0000-0xEFFFF would be the next possibility. If we can verify that bootloaders and operating systems can handle a reserved area below 0x9FFFF, that might be a viable choice as well.
The good thing about v3 is that we can change the CAR location easily, so postponing the decision will work as well.
Regards, Carl-Daniel
On Mon, Sep 08, 2008 at 04:11:35AM +0200, Carl-Daniel Hailfinger wrote:
On 08.09.2008 03:37, Kevin O'Connor wrote:
Any memory that coreboot might clobber would need to be reserved, and 0xc0000 can't be reserved because vga option roms expect to be located there.
OK. The problem here is that large multicore machines need 48 kB CAR size, probably more in the future. Are VGA option ROMs guaranteed to be 16 kB or smaller?
No - I have vga roms nearly 64KB in size. I don't know if there is an upper limit.
An alternative (as you mentioned in an early email) would be to save and restore some area of memory below 1MB.
Yes, but the problem is that the CAR area can't be saved before enabling CAR. That means we have to reserve the memory. Let me summarize the current black list:
- 0x00000-0x9FFFF is low 640 kB. May break bootloaders and 16-bit OS.
Right.
- 0xA0000-0xAFFFF is VGA graphics memory mapped area.
- 0xB0000-0xB7FFF is ancient monochrome memmapped, but may still be
decoded by newer VGA cards.
- 0xB8000-0xBFFFF is VGA text mode memory mapped area.
I wonder if one could back this area with memory during resume, and then return control to the vga cards before returning to the OS.
- 0xC0000-???? is VGA ROM location.
You can almost certainly reserve space in the 0xe0000 area. However, doing so limits the space for other option roms.
- 0xF0000-0xFFFFF is used by SeaBIOS.
Something could be worked out here. We could backup seabios and restore it before resume completes. It'd be ugly though.
-Kevin
Carl-Daniel Hailfinger wrote:
Yes, but the problem is that the CAR area can't be saved before enabling CAR. That means we have to reserve the memory. Let me summarize the current black list:
- 0x00000-0x9FFFF is low 640 kB. May break bootloaders and 16-bit OS.
- 0xA0000-0xAFFFF is VGA graphics memory mapped area.
- 0xB0000-0xB7FFF is ancient monochrome memmapped, but may still be
decoded by newer VGA cards.
- 0xB8000-0xBFFFF is VGA text mode memory mapped area.
- 0xC0000-???? is VGA ROM location.
- 0xF0000-0xFFFFF is used by SeaBIOS.
IMO, the first choice would be 0xC4000-0xCFFFF (if VGA ROMs are 16 kB or smaller). 0xE0000-0xEFFFF would be the next possibility. If we can verify that bootloaders and operating systems can handle a reserved area below 0x9FFFF, that might be a viable choice as well.
Late to this discussion but here are my $.02.
Most VBIOS may truncate themselves to be smaller after init but the initial image size is 32K or larger these days.
E0000 is the normal location for BIOS expansion. I recommend allocating from EFFFF down and leave room at the bottom for more expansion ROMs.
Marc
Kevin O'Connor wrote:
Hi,
On Sun, Sep 07, 2008 at 11:40:51PM +0200, Rudolf Marek wrote:
CAR will write to memory locations below 1M. There are three ways to cope with that:
- Back up that area during suspend and restore it as last instruction
of resume. 2. Declare the CAR area (48 kB) as reserved memory.
Imho this is OK, and easiest.
I don't think one can mark 48KB reserved below 0xA0000. I've found that boot loaders are picky about any reserved memory below 1MB.
It's normal to reserve the ebda (typically 0x9fc00 to 0xa0000), but I seem to recall reading that an EBDA over 16KB will confuse some programs. Using the EBDA area would also likely break SeaBIOS.
Isn't BDA from 0x400 to 0x500 and EBDA from 0x500 on?
Stefan
Stefan Reinauer wrote:
Kevin O'Connor wrote:
It's normal to reserve the ebda (typically 0x9fc00 to 0xa0000), but I seem to recall reading that an EBDA over 16KB will confuse some programs. Using the EBDA area would also likely break SeaBIOS.
Isn't BDA from 0x400 to 0x500 and EBDA from 0x500 on?
Kevin is correct. The EBDA location is stored in the BDA @ 40E and is typically 9fc00.
Marc
Hi,
On Sun, Sep 07, 2008 at 10:59:13PM +0200, Carl-Daniel Hailfinger wrote: [...]
CAR will write to memory locations below 1M. There are three ways to cope with that:
[...]
- Write excessively clever and fragile code which performs a double
stack switch during resume.
[...]
- Will NOT work for Geode, may not work for Intel and VIA. The existing
CAR enabling/disabling code will seem trivial in comparison.
Why can't the code use a new stack after CAR is disabled?
To be clear, I think moving the stack would be a bad idea. However, I don't see why the code can't just start using a new stack.
Right now, the only stack variable that is shared between CAR and post-CAR is 'archive' (in stage1_main() ). I would think one could manually copy it from the CAR stack to a post-CAR global variable. (Or just rebuild it from scratch.)
I'm thinking - one could implement a small assembler trampoline function that took two parameters - the new stack location and the function to jump to. The assembler would only need to set %esp and jump to the new function.
This would still require memory under 1MB for car, but at least stage2 could run with a full stack and globals that run in reserved memory.
Have I missed something?
-Kevin
Hi,
On 08.09.2008 02:06, Kevin O'Connor wrote:
On Sun, Sep 07, 2008 at 10:59:13PM +0200, Carl-Daniel Hailfinger wrote: [...]
CAR will write to memory locations below 1M. There are three ways to cope with that:
[...]
- Write excessively clever and fragile code which performs a double
stack switch during resume.
[...]
- Will NOT work for Geode, may not work for Intel and VIA. The existing
CAR enabling/disabling code will seem trivial in comparison.
Why can't the code use a new stack after CAR is disabled?
To be clear, I think moving the stack would be a bad idea. However, I don't see why the code can't just start using a new stack.
Right now, the only stack variable that is shared between CAR and post-CAR is 'archive' (in stage1_main() ).
Please update your v3 tree. Variables shared between CAR and post-CAR were introduced with their own framework over 100 revisions ago, but they were available and used without a formal framework over 270 revisions ago for the printk buffer address.
I would think one could manually copy it from the CAR stack to a post-CAR global variable. (Or just rebuild it from scratch.)
See above.
I'm thinking - one could implement a small assembler trampoline function that took two parameters - the new stack location and the function to jump to. The assembler would only need to set %esp and jump to the new function.
This would still require memory under 1MB for car, but at least stage2 could run with a full stack and globals that run in reserved memory.
Have I missed something?
Yes. If we can get some memory reserved below 1 MB for CAR, there is no need to move the stack. Although the stack does grow quite a bit beyond the CAR area once we are post-CAR, we can easily back up all of lowmem (or selective chunks of it) in reserved memory at the top of RAM. That allows us to leave the stack completely alone until we hand off control to the payload (and we won't call a payload for the S3 resume case).
By the way, here's a nice small problem for you, Kevin: How can we combine SeaBIOS and suspend-to-RAM? Either SeaBIOS needs to have its own S3 resume path (machine-specific) or we perform VGA init in coreboot.
Regards, Carl-Daniel
On Mon, Sep 08, 2008 at 02:28:15AM +0200, Carl-Daniel Hailfinger wrote:
On 08.09.2008 02:06, Kevin O'Connor wrote:
Why can't the code use a new stack after CAR is disabled?
To be clear, I think moving the stack would be a bad idea. However, I don't see why the code can't just start using a new stack.
Right now, the only stack variable that is shared between CAR and post-CAR is 'archive' (in stage1_main() ).
Please update your v3 tree.
Okay - I see it's used more frequently now.
I don't think it fundamentally changes much though. One could copy 'struct global_vars' to a permanent location before calling stage2.
Doing so would require global_vars() to evaluate to different locations depending on the stage. Unfortunately, this would limit sharing of code between initram and stage2. Stage2 is compressed though - is it still a problem?
(An alternative would be to pass the gloval_vars address to every function that needed it - one could dress it up with macros, but it's probably too ugly.)
This would still require memory under 1MB for car, but at least stage2 could run with a full stack and globals that run in reserved memory.
Have I missed something?
Yes. If we can get some memory reserved below 1 MB for CAR, there is no need to move the stack. Although the stack does grow quite a bit beyond the CAR area once we are post-CAR, we can easily back up all of lowmem (or selective chunks of it) in reserved memory at the top of RAM. That allows us to leave the stack completely alone until we hand off control to the payload (and we won't call a payload for the S3 resume case).
I suspect using ram under 1MB is going to be more problematic than you think. I hope to be proven wrong. :-)
By the way, here's a nice small problem for you, Kevin: How can we combine SeaBIOS and suspend-to-RAM? Either SeaBIOS needs to have its own S3 resume path (machine-specific) or we perform VGA init in coreboot.
I thought S3 restore didn't require a BIOS VGA init. My understanding was - turn on ram and jump to the OS. I wasn't sure even if stage2 had to be run. I'm no expert though.
There is some good info in the acpi spec (do a google search for 'ACPIspec30b.pdf') in section 15.1.3.
-Kevin
On 08.09.2008 04:34, Kevin O'Connor wrote:
On Mon, Sep 08, 2008 at 02:28:15AM +0200, Carl-Daniel Hailfinger wrote:
On 08.09.2008 02:06, Kevin O'Connor wrote:
Why can't the code use a new stack after CAR is disabled?
To be clear, I think moving the stack would be a bad idea. However, I don't see why the code can't just start using a new stack.
Right now, the only stack variable that is shared between CAR and post-CAR is 'archive' (in stage1_main() ).
Please update your v3 tree.
Okay - I see it's used more frequently now.
I don't think it fundamentally changes much though. One could copy 'struct global_vars' to a permanent location before calling stage2.
Doing so would require global_vars() to evaluate to different locations depending on the stage. Unfortunately, this would limit sharing of code between initram and stage2. Stage2 is compressed though - is it still a problem?
We have problems keeping the code bug-free even with one stack location and the various ABIs we use in coreboot. Having two stacks at different locations before and after CAR has been ruled out for v3 after long design and implementation discussions.
(An alternative would be to pass the gloval_vars address to every function that needed it - one could dress it up with macros, but it's probably too ugly.)
Ugly indeed.
This would still require memory under 1MB for car, but at least stage2 could run with a full stack and globals that run in reserved memory.
Have I missed something?
Yes. If we can get some memory reserved below 1 MB for CAR, there is no need to move the stack. Although the stack does grow quite a bit beyond the CAR area once we are post-CAR, we can easily back up all of lowmem (or selective chunks of it) in reserved memory at the top of RAM. That allows us to leave the stack completely alone until we hand off control to the payload (and we won't call a payload for the S3 resume case).
I suspect using ram under 1MB is going to be more problematic than you think. I hope to be proven wrong. :-)
The docs of various processors (including latest 64bit silicon) state that the CAR area MUST be below 1 MB. That 1 MB boundary is mentioned explicitly multiple times, so I guess we have to cope with it.
By the way, here's a nice small problem for you, Kevin: How can we combine SeaBIOS and suspend-to-RAM? Either SeaBIOS needs to have its own S3 resume path (machine-specific) or we perform VGA init in coreboot.
I thought S3 restore didn't require a BIOS VGA init. My understanding was - turn on ram and jump to the OS. I wasn't sure even if stage2 had to be run. I'm no expert though.
Linux expects the VGA card to come up initialized on S3 resume. You can work around "broken" BIOSes by telling Linux to rerun the VGA BIOS on resume. See the s3_bios kernel parameter for details.
There is some good info in the acpi spec (do a google search for 'ACPIspec30b.pdf') in section 15.1.3.
Will do. Three years ago, I was heavily involved in Linux S3 because my laptop had its own ideas about resuming with graphics. I fixed my laptop, but that journey cost me a few months and I am determined to make sure this doesn't happen with coreboot.
Regards, Carl-Daniel
Carl-Daniel Hailfinger wrote:
The docs of various processors (including latest 64bit silicon) state that the CAR area MUST be below 1 MB. That 1 MB boundary is mentioned explicitly multiple times, so I guess we have to cope with it.
This is not a generally valid assumption. On core duo, the CAR area needs to be 1M below the ROM.
Stefan
On 08.09.2008 14:45, Stefan Reinauer wrote:
Carl-Daniel Hailfinger wrote:
The docs of various processors (including latest 64bit silicon) state that the CAR area MUST be below 1 MB. That 1 MB boundary is mentioned explicitly multiple times, so I guess we have to cope with it.
This is not a generally valid assumption. On core duo, the CAR area needs to be 1M below the ROM.
That's really bad news because it conflicts with the v3 design, unless there is a way to keep the stack location somehow.
Stefan, you're the core duo expert. Do you see any way to have the same stack location during and after CAR?
Regards, Carl-Daniel
Carl-Daniel Hailfinger wrote:
On 08.09.2008 14:45, Stefan Reinauer wrote:
Carl-Daniel Hailfinger wrote:
The docs of various processors (including latest 64bit silicon) state that the CAR area MUST be below 1 MB. That 1 MB boundary is mentioned explicitly multiple times, so I guess we have to cope with it.
This is not a generally valid assumption. On core duo, the CAR area needs to be 1M below the ROM.
That's really bad news because it conflicts with the v3 design, unless there is a way to keep the stack location somehow.
Stefan, you're the core duo expert. Do you see any way to have the same stack location during and after CAR?
No. There is no RAM at that position.
On 08.09.2008 17:23, Stefan Reinauer wrote:
Carl-Daniel Hailfinger wrote:
On 08.09.2008 14:45, Stefan Reinauer wrote:
Carl-Daniel Hailfinger wrote:
The docs of various processors (including latest 64bit silicon) state that the CAR area MUST be below 1 MB. That 1 MB boundary is mentioned explicitly multiple times, so I guess we have to cope with it.
This is not a generally valid assumption. On core duo, the CAR area needs to be 1M below the ROM.
That's really bad news because it conflicts with the v3 design, unless there is a way to keep the stack location somehow.
Stefan, you're the core duo expert. Do you see any way to have the same stack location during and after CAR?
No. There is no RAM at that position.
That means we either - have to tell gcc that the stack moved in the middle of a function or - redesign v3 stage1 completely.
That sucks. Very much.
Regards, Carl-Daniel
On Mon, Sep 8, 2008 at 8:38 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
That means we either
- have to tell gcc that the stack moved in the middle of a function or
- redesign v3 stage1 completely.
That sucks. Very much.
it's not that hard. You split stage1 in half. I had an implementation of this at one point until we decided to return from disable_car().
My opinion, then and now, is that NOT returning from disable_car is a more general solution, which future-proofs us against a stupid future CPU that could not return from disable_car(). There, I've said it.
ron
Carl-Daniel Hailfinger wrote:
That means we either
- have to tell gcc that the stack moved in the middle of a function or
- redesign v3 stage1 completely.
That sucks. Very much.
Hm, that's a regression.. The scenario works fine in v2
On Mon, Sep 08, 2008 at 05:38:59PM +0200, Carl-Daniel Hailfinger wrote:
On 08.09.2008 17:23, Stefan Reinauer wrote:
No. There is no RAM at that position.
That means we either
- have to tell gcc that the stack moved in the middle of a function or
- redesign v3 stage1 completely.
I don't think that is true.
As before, I think _moving_ the stack is a bad idea. However, I don't see any reason not to start using a new stack and discard the old. Doing so is both simple and reliable.
I've attached a code snippet below - it's only to illustrate the general idea.
That said, I think having disable_car() jump to the next stage is probably faster and more flexible.
-Kevin
Index: arch/x86/stage1.c =================================================================== --- arch/x86/stage1.c (revision 861) +++ arch/x86/stage1.c (working copy) @@ -139,6 +139,8 @@ } #endif /* CONFIG_PAYLOAD_ELF_LOADER */
+static struct mem_file GlobalArchive; + /** * This function is called from assembler code with its argument on the * stack. Force the compiler to generate always correct code for this case. @@ -232,6 +234,20 @@
printk(BIOS_DEBUG, "Done RAM init code\n");
+ // Memory running - copy variables in CAR area that are needed + // to a permanent area. + GlobalArchive = archive; + + // Jump to second part of stage1 with a permanent stack. + asm volatile ( + "movl 0x200000, %esp\n" + "jmp stage1_main_post_initram\n"); +} + +void stage1_main_post_initram() +{ + struct mem_file archive = GlobalArchive; + /* Turn off Cache-As-Ram */ disable_car();
On 09.09.2008 02:46, Kevin O'Connor wrote:
On Mon, Sep 08, 2008 at 05:38:59PM +0200, Carl-Daniel Hailfinger wrote:
On 08.09.2008 17:23, Stefan Reinauer wrote:
No. There is no RAM at that position.
That means we either
- have to tell gcc that the stack moved in the middle of a function or
- redesign v3 stage1 completely.
I don't think that is true.
Well, if the stack location during CAR is in a place that will have no RAM after CAR, we must move the stack or use virtual memory addresses (fun!).
As before, I think _moving_ the stack is a bad idea. However, I don't see any reason not to start using a new stack and discard the old. Doing so is both simple and reliable.
I've attached a code snippet below - it's only to illustrate the general idea.
Yes, and it won't work because there can't be global variables in stage1 because there's no place to store them. We already had code to do that jump a few hundred revisions ago and we killed it because it was extremely difficult to follow. The stack switching is a processor dependent operation because it has to be coupled with disabling CAR. That means you have to follow calls a few levels deep just to see how the end of stage1 is executed.
That said, I think having disable_car() jump to the next stage is probably faster and more flexible.
It is a world of pain and I'm still determined to find a way to avoid it, possibly by mapping some RAM into the CAR area through the use of virtual memory.
Regards, Carl-Daniel
On Tue, Sep 09, 2008 at 03:22:38AM +0200, Carl-Daniel Hailfinger wrote:
On 09.09.2008 02:46, Kevin O'Connor wrote:
I've attached a code snippet below - it's only to illustrate the general idea.
Yes, and it won't work because there can't be global variables in stage1 because there's no place to store them.
We can't access memory after initram completes? Global variables are just memory addresses. One clearly can not access them before memory is available - but why can't we access them after memory is up?
The stack switching is a processor dependent operation because it has to be coupled with disabling CAR.
Okay - can you elaborate on what those dependencies are? Is there a phase where we can access CAR but not main memory?
-Kevin
On 09.09.2008 03:49, Kevin O'Connor wrote:
On Tue, Sep 09, 2008 at 03:22:38AM +0200, Carl-Daniel Hailfinger wrote:
On 09.09.2008 02:46, Kevin O'Connor wrote:
I've attached a code snippet below - it's only to illustrate the general idea.
Yes, and it won't work because there can't be global variables in stage1 because there's no place to store them.
We can't access memory after initram completes? Global variables are just memory addresses. One clearly can not access them before memory is available - but why can't we access them after memory is up?
For that we have stage2 global variables.
The stack switching is a processor dependent operation because it has to be coupled with disabling CAR.
Okay - can you elaborate on what those dependencies are? Is there a phase where we can access CAR but not main memory?
Well, switching off CAR is processor specific. After switching off CAR, your old stack will be invalid, so you must switch stacks before that. However, you can't switch the stack in the middle of a function and you must avoid cache eviction of the old stack before you have the new stack running. That pretty much forces you to have stack switch and CAR disabling as one giant block of asm.
Regards, Carl-Daniel
Hi Carl-Daniel,
On Tue, Sep 09, 2008 at 04:10:54AM +0200, Carl-Daniel Hailfinger wrote:
On 09.09.2008 03:49, Kevin O'Connor wrote:
On Tue, Sep 09, 2008 at 03:22:38AM +0200, Carl-Daniel Hailfinger wrote:
Yes, and it won't work because there can't be global variables in stage1 because there's no place to store them.
We can't access memory after initram completes? Global variables are just memory addresses. One clearly can not access them before memory is available - but why can't we access them after memory is up?
For that we have stage2 global variables.
But, aesthetics aside, do you agree we can write to global variables in stage1 if we are sure not to use them prior to initram?
Okay - can you elaborate on what those dependencies are? Is there a phase where we can access CAR but not main memory?
Well, switching off CAR is processor specific. After switching off CAR, your old stack will be invalid, so you must switch stacks before that.
Right - that was what my sample code did. It switches to a new stack prior to calling disable_car().
However, you can't switch the stack in the middle of a function
Agreed.
and you must avoid cache eviction of the old stack before you have the new stack running.
I don't understand this point. The memory accesses for the new stack shouldn't evict the CAR area because the memory is still marked as non-cached.
That pretty much forces you to have stack switch and CAR disabling as one giant block of asm.
As I stated before I think doing that is probably the fastest and most flexible design.
I don't see why it is mandatory though - perhaps you could elaborate on what I'm missing.
-Kevin
On Mon, Sep 8, 2008 at 8:23 AM, Stefan Reinauer stepan@coresystems.de wrote:
Carl-Daniel Hailfinger wrote:
Stefan, you're the core duo expert. Do you see any way to have the same stack location during and after CAR?
No. There is no RAM at that position.
OK, can we get a confirmation here one way or another on core 2 duo. There is no ram at "that" position. I assume "that" is 0xc0000? Is it possible to ever have CARBASE where there is RAM or is this a hardware limit. If there is no RAM at CARBASE, then it is not possible to return from disable_car and we need a simple redesign.
The CAR decision in v3 that was taken some time ago was to assume that we could return from disable_car.
If we can not return from disable_car, then disable_car needs to work as follows: disable_car(void (*f)(struct sysinfo *s), struct sysinfo *sysinfo) { /* copy sysinfo to RAM */ /* set ESP to top of sysinfo */ /* disable CAR*/ /* continue */ f(sysinfo); }
This is pretty much what we have in v2.
I'm not expressing an opinion here, just stating what I think is needed if disable_car can not be returned from.
thanks
ron
ron minnich wrote:
On Mon, Sep 8, 2008 at 8:23 AM, Stefan Reinauer stepan@coresystems.de wrote:
Carl-Daniel Hailfinger wrote:
Stefan, you're the core duo expert. Do you see any way to have the same stack location during and after CAR?
No. There is no RAM at that position.
OK, can we get a confirmation here one way or another on core 2 duo. There is no ram at "that" position. I assume "that" is 0xc0000? Is it possible to ever have CARBASE where there is RAM or is this a hardware limit. If there is no RAM at CARBASE, then it is not possible to return from disable_car and we need a simple redesign.
No, as I wrote, it's 0xFFxxxxxx. Putting it in the low 1M will not work.
The CAR decision in v3 that was taken some time ago was to assume that we could return from disable_car.
Why would this not be possible? Change %sp and return.
Stefan
On Mon, Sep 8, 2008 at 8:47 AM, Stefan Reinauer stepan@coresystems.de wrote:
Why would this not be possible? Change %sp and return.
if you change sp you really can not return. That's the issue.
ron
ron minnich wrote:
Why would this not be possible? Change %sp and return.
if you change sp you really can not return. That's the issue.
disable_car() would actually return to the caller, but the caller may make assumptions about the stack, correct?
Anyway, I think call (that will also never return) from disable_car() is what I like best so far. But I don't think the new function should be a parameter, we should be generic enough to always continue in the same location.
//Peter
ron minnich wrote:
On Mon, Sep 8, 2008 at 8:47 AM, Stefan Reinauer stepan@coresystems.de wrote:
Why would this not be possible? Change %sp and return.
if you change sp you really can not return. That's the issue.
why not? Assuming you created a valid stack before you switch esp. But that's really no magic.
On Mon, Sep 8, 2008 at 10:00 AM, Stefan Reinauer stepan@coresystems.de wrote:
ron minnich wrote:
On Mon, Sep 8, 2008 at 8:47 AM, Stefan Reinauer stepan@coresystems.de wrote:
Why would this not be possible? Change %sp and return.
if you change sp you really can not return. That's the issue.
why not? Assuming you created a valid stack before you switch esp. But that's really no magic.
crafting a return frame is easy. Recreating all of a stack, at a different address, is easy for all the parts that are not impossible. The impossible parts are hard.
ron
On Sun, Sep 7, 2008 at 5:06 PM, Kevin O'Connor kevin@koconnor.net wrote:
Why can't the code use a new stack after CAR is disabled?
To be clear, I think moving the stack would be a bad idea. However, I don't see why the code can't just start using a new stack.
I don't want to revisit this if I don't have to :=)
This discussion of "use old stack"/"use new stack" went on for a bit, and we went with "use old stack" for a number of reasons. One big reason was that our production bios experts told us we really ought to be able to keep using the stack after disabling car, and we have shown with v3 that this is possible BUT BUT BUT:
we need to reserve 2x the active stack area (on entry to CAR) to properly use the old stack on K8. Just FYI.
(NOT the whole CAR area, just the area of stack that is active when we call disaable_car).
This is easy but it's important to remember it.
ron
On 08.09.2008 05:54, ron minnich wrote:
On Sun, Sep 7, 2008 at 5:06 PM, Kevin O'Connor kevin@koconnor.net wrote:
Why can't the code use a new stack after CAR is disabled?
To be clear, I think moving the stack would be a bad idea. However, I don't see why the code can't just start using a new stack.
I don't want to revisit this if I don't have to :=)
This discussion of "use old stack"/"use new stack" went on for a bit, and we went with "use old stack" for a number of reasons. One big reason was that our production bios experts told us we really ought to be able to keep using the stack after disabling car, and we have shown with v3 that this is possible BUT BUT BUT:
we need to reserve 2x the active stack area (on entry to CAR) to properly use the old stack on K8. Just FYI.
Well, that's what the code requires now, but it is easy to change that without changing our working stack-backup-restore inline asm. We can back up the area clobbered by the stack backup before backing up the stack. The alternative of backing up the stack to a reserved area at the top of memory won't work due to inline asm peculiarities.
(NOT the whole CAR area, just the area of stack that is active when we call disaable_car).
This is easy but it's important to remember it.
For multiprocessor environments, these two are basically identical.
Regards, Carl-Daniel
Rudolf Marek wrote:
If needed, writing to SLP register might be traped by SMM, and BIOS can save some values to NVRAM regs, sometimes found in chipsets (memory timing etc) to ease the startup. But we dont need that we are fast anyway.
Some chipsets even require some bits to be stored in nvram as they do not support probing/reading them when coming out of S3.
On 08.09.2008 14:31, Stefan Reinauer wrote:
Rudolf Marek wrote:
If needed, writing to SLP register might be traped by SMM, and BIOS can save some values to NVRAM regs, sometimes found in chipsets (memory timing etc) to ease the startup. But we dont need that we are fast anyway.
Some chipsets even require some bits to be stored in nvram as they do not support probing/reading them when coming out of S3.
Do these chipsets also support S3-surviving scratch registers we could use instead of NVRAM?
Regards, Carl-Daniel
Carl-Daniel Hailfinger wrote:
On 08.09.2008 14:31, Stefan Reinauer wrote:
Rudolf Marek wrote:
If needed, writing to SLP register might be traped by SMM, and BIOS can save some values to NVRAM regs, sometimes found in chipsets (memory timing etc) to ease the startup. But we dont need that we are fast anyway.
Some chipsets even require some bits to be stored in nvram as they do not support probing/reading them when coming out of S3.
Do these chipsets also support S3-surviving scratch registers we could use instead of NVRAM?
No. Not in a sufficient way at least.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi,
Well I think we do not care much about the state of those registers, hence our approach is to redo the whole init (the ACPI specs allows this).
For example VIA has extra NVRAM of 256 bytes which survives the S3.
Rudolf
Carl-Daniel Hailfinger wrote:
intraphase is initram? Would it make sense to have a fast path in initram for this?
Yes, it is even required.
<ruik> 4) when creating ACPI tables look to that place, in one table there will be OS waking vector <ruik> 5) after all done, jump to OS instead of payload, switch A20 on go to real mode and jump <ruik> 6) do this all steps in reserved memory, do not corrupt system memory used by OS
I think 6) in particular deserves some consideration.
- is really easy with v3. A lot easier than with v2. I think I wrote a
design doc about that one year ago.
Have a pointer?
However, I am surprised that the SuperI/O acts as a power supply for RAM.
The SuperIO has GPIOs. These control various things, among them can be the power lines of devices, such as WiFi or even RAM. Software needs to be able to control RAM power, so either the southbridge GPIOs or the SuperIO GPIOs are used for that.
On 08.09.2008 14:29, Stefan Reinauer wrote:
Carl-Daniel Hailfinger wrote:
intraphase is initram? Would it make sense to have a fast path in initram for this?
Yes, it is even required.
<ruik> 4) when creating ACPI tables look to that place, in one table there will be OS waking vector <ruik> 5) after all done, jump to OS instead of payload, switch A20 on go to real mode and jump <ruik> 6) do this all steps in reserved memory, do not corrupt system memory used by OS
I think 6) in particular deserves some consideration.
- is really easy with v3. A lot easier than with v2. I think I wrote a
design doc about that one year ago.
Have a pointer?
I couldn't find the mail after a quick search, but it basically boils down to: - Declare the CAR area as reserved. - Declare some scratch space at the top of memory as reserved. - When loading any LAR member which is not XIP, back up the memory that would be clobbered to the reserved area at the top of memory. - Make sure to store any created tables only in specially reserved memory. - After finishing execution of a LAR member, restore the clobbered memory from backup.
However, I am surprised that the SuperI/O acts as a power supply for RAM.
The SuperIO has GPIOs. These control various things, among them can be the power lines of devices, such as WiFi or even RAM. Software needs to be able to control RAM power, so either the southbridge GPIOs or the SuperIO GPIOs are used for that.
Cool. Could you add that very important information to the wiki somewhere?
Regards, Carl-Daniel
* Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [080908 17:17]:
- Declare the CAR area as reserved.
What is it again that keeps us from putting CAR area somewhere where there's no real RAM?
- When loading any LAR member which is not XIP, back up the memory that
would be clobbered to the reserved area at the top of memory.
Why don't we just put it into the reserved area to begin with, instead of doing those luxations? Creating a generic relocator does not make much sense, because stuff like the SeaBIOS area will not have to be preserved.
- Make sure to store any created tables only in specially reserved memory.
Now that's where it's getting really hard. Linux always keeps the first two pages reserved though. It also reserves most tables itself (which is why you get those page 0 reserved twice warnings when you put the mptable into page 0)
The SuperIO has GPIOs. These control various things, among them can be the power lines of devices, such as WiFi or even RAM. Software needs to be able to control RAM power, so either the southbridge GPIOs or the SuperIO GPIOs are used for that.
Cool. Could you add that very important information to the wiki somewhere?
I don't think it's magic,.. but where to put it? Can someone start an S3/Resume page?
Regards, Carl-Daniel
On 08.09.2008 17:34, Stefan Reinauer wrote:
- Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [080908 17:17]:
- Declare the CAR area as reserved.
What is it again that keeps us from putting CAR area somewhere where there's no real RAM?
The current v3 stage1 design may fail. I don't know of a way to tell gcc that the stack moved in the middle of a function. Maybe there is one.
- When loading any LAR member which is not XIP, back up the memory that
would be clobbered to the reserved area at the top of memory.
Why don't we just put it into the reserved area to begin with, instead of doing those luxations? Creating a generic relocator does not make much sense, because stuff like the SeaBIOS area will not have to be preserved.
Unless you want a linker running on boot, you have to know the location of the code and data in advance. That means the reserved area would have to be independent of actual RAM size (i.e. not at the top of RAM) and machines with less RAM than the predesignated reserved area location would fail during runtime.
- Make sure to store any created tables only in specially reserved memory.
Now that's where it's getting really hard. Linux always keeps the first two pages reserved though. It also reserves most tables itself (which is why you get those page 0 reserved twice warnings when you put the mptable into page 0)
Decide on the first boot where to put the tables, then declare that area as reserved. Looks easy to me.
The SuperIO has GPIOs. These control various things, among them can be the power lines of devices, such as WiFi or even RAM. Software needs to be able to control RAM power, so either the southbridge GPIOs or the SuperIO GPIOs are used for that.
Cool. Could you add that very important information to the wiki somewhere?
I don't think it's magic,.. but where to put it? Can someone start an S3/Resume page?
Don't we already have one? Seems you're right and we have to start a page.
Regards, Carl-Daniel
Carl-Daniel Hailfinger wrote:
On 08.09.2008 17:34, Stefan Reinauer wrote:
- Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [080908 17:17]:
- Declare the CAR area as reserved.
What is it again that keeps us from putting CAR area somewhere where there's no real RAM?
The current v3 stage1 design may fail. I don't know of a way to tell gcc that the stack moved in the middle of a function. Maybe there is one.
roughly: asm volatile ("movl newstack, %eax\n movl %eax, %esp\n")
Why don't we just put it into the reserved area to begin with, instead of doing those luxations? Creating a generic relocator does not make much sense, because stuff like the SeaBIOS area will not have to be preserved.
Unless you want a linker running on boot, you have to know the location of the code and data in advance.
We could set up a relocation mapping. That's what FILO does to cope with this issue.
On Mon, Sep 8, 2008 at 9:00 AM, Stefan Reinauer stepan@coresystems.de wrote:
roughly: asm volatile ("movl newstack, %eax\n movl %eax, %esp\n")
and your entire call chain and all automatics on the stack are gone. And you can't return from disable_car.
Moving the stack in the general case won't work. Better to call another function -- i.e. disable_car never returns -- that's we do do in v2 today.
We could set up a relocation mapping. That's what FILO does to cope with this issue.
It seems kind of complex and it is very architecture dependent. If we assume there is no return from disable_car, life is very much simpler.
ron
ron minnich wrote:
On Mon, Sep 8, 2008 at 9:00 AM, Stefan Reinauer stepan@coresystems.de wrote:
roughly: asm volatile ("movl newstack, %eax\n movl %eax, %esp\n")
and your entire call chain and all automatics on the stack are gone. And you can't return from disable_car.
So are you saying it is incredible hard to produce that call chain from scratch, or copy it over? I really don't think so.
Moving the stack in the general case won't work. Better to call another function -- i.e. disable_car never returns -- that's we do do in v2 today.
Works fine for me.
We could set up a relocation mapping. That's what FILO does to cope with this issue.
It seems kind of complex and it is very architecture dependent.
Yes, as is a bios. We're talking about details in Cache as RAM here,... that's much CPU specific, whereas the FILO reloc is "only" x86 dependent. Though, all modern CPUs have a mechanism like that, should we ever try to find out we need that at all.
If we assume there is no return from disable_car, life is very much simpler.
Ok, why don't we do that?
On Mon, Sep 8, 2008 at 9:57 AM, Stefan Reinauer stepan@coresystems.de wrote:
ron minnich wrote:
and your entire call chain and all automatics on the stack are gone. And you can't return from disable_car.
So are you saying it is incredible hard to produce that call chain from scratch, or copy it over? I really don't think so.
any pointers on stack are wrong. You can't tell data from pointers. And so on. I think it's an idea that could really get you in trouble.
I don't feel that moving the stack, and all it contains, to another location is a good idea.
Moving the stack in the general case won't work. Better to call another function -- i.e. disable_car never returns -- that's we do do in v2 today.
Works fine for me.
me too.
If we assume there is no return from disable_car, life is very much simpler.
Ok, why don't we do that?
See the January discussion. I even prototyped it. I still feel it is clean in an architecture-independent sense, and in a *implementation* - independent sense.
Still, I want to make sure: do the rules for core 2 duo make it impossible to return from disable_car with the same stack?
Here is how we return from stack on on k8.
disable_car(){ copy CAR area to RAM disable car copy RAM to CAR return ]
Would this not work on core 2? ron
The following pointer to the list archive (and followup mails) should also give some insight into what we discussed regarding CAR and S3 back in January: http://www.coreboot.org/pipermail/coreboot/2008-January/029155.html
Regards, Carl-Daniel