> > do this needs some firmware support.  Just something to think about,
> 
> exactly.  in all but POS (ACPI has a different term) the CPU is reset,
> as is some other hardware (ram ctlr).  SO upon CPU being powered again,
> it will reset the same as if the whole system is cold-started (not sure -
> what's difference between reset and INIT pin?)  so the reset vector
> 0xffff0 code must branch at somepoint based on a flag (cold-start or
> resume) and do things differently.  for suspend to ram, this code is mostly
> in linuxbios already (just re-init ram controller and things like that).
> for suspend to disk, additionally (with current architecture) linux
> would have to start to  a certain point, then load image back into
> ram (from swap?) I think special case of kexec to load ram image
> from swap area or similar might be appropriate, that could
> be called in a kernel thread when a flag is passed to linux(in rom)
> from linuxbios.

In ACPI, there are 6 states wrt to sleeping (S0 - S5)

S0 - Normal Operation
S1 - All system context is maintained, except for caches (including CPU
        state, memory and chipset state) (No firmware support needed).
S2/S3 - Suspend to RAM. CPU context is lost. In S3, devices are either put
        to sleep or turned off.
        Execution resumes from the reset vector. From there, the BIOS is
        required to:
                - set MSRs and MTRRs
                - init cache
                - take mem out of self-refresh
                - jump the the waking vector [1]
        Note that S2 and S3 are nearly identical, but I have never
        personally seen a system that supports S2 for some reason.

S4 - Suspend to disk.
        - All system context lost; memory image written to disk.
        - There are two methods for accomplishing this, and OS-initiated
        and a BIOS-initiated method.
        In the latter method, the OS makes the request to enter S4 via 
        a bit in the FACS table. The BIOS then saves the memory and 
        chipset context to disk and enters the sleep state. On exit, it
        initializes boot devices only, restores the memory and chipset
        contexts and jumps to the waking vector.
        In the OS-initiated method, the OS does the saving of state and
        entering the sleep mode. When the system is powered up again, it
        initializes everything to is "POST condition" and starts to boot
        the OS as it would on a normal boot. It is up to the boot loader
        to determine that it is waking from sleep and handle it
        appropriately. The BIOS is also responsible for updating the
        "hardware signature", which somehow describes the devices that
        are in the system. This is to meant to support devices that could
        have been added while asleep.
S5 - Soft off. This is just for the OS to power the system off by writing
        to an ACPI register (i.e. It's not a sleep state).

(paraphrased from Chapter 9 of the ACPI 2.0 spec)

[1] - The waking vector is a 32-bit address in the Firmware ACPI Control
Structure (FACS) tells the BIOS the place to jump to when waking from
sleep. If the value is non-zero, it is assumed to be a valid address.
The BIOS is responsible for supplying the FACS table, so it should know
where it is in memory.

> > though I bet having an address in CMOS of which image to boot on power
> 
> I believe the standby power well in the PIIX4 maintains this state, but
> cmos sounds like an appropriate place to store this.

In S2 and S3, memory context is maintained, and in S4 (BIOS-initiated),
the BIOS restores memory, so the FACS is in memory (and no need to store
it in CMOS). In OS-initiated S4, it just loads the boot sector as it would
on a normal boot, so it doesn't need to know that we are returning from
sleep. The OS in this case could check a magical location on disk to see
if it is returning from sleep.

I have been working implementing the sleep states on Linux (well, at least
S3), and have gotten as far as getting the kernel to restore processor
and execution context from the waking vector in a test environment. The
kernel ACPI implementation doesn't currently have support for setting the
wake capabilities of any devices or re-enumerating the buses, so it'll be
a while before it actually works.

I figure that with linuxbios, the entire process could be streamlined,
especially with S4. It just needs to have ACPI support, at least as far as
tables are concerned. Devices power management is still a long ways off,
esp. in the kernel.

        -pat

Reply via email to