Sleeping Beauty
NetBSD on modern laptops
Jörg Sonnenberger
Jared D. McNeill
Outline
- Motivation & Goals
- The NetBSD Powermanagement Framework (PMF)
- The ACPI infrastructure
- Video devices
- Outlook
Motivation
- My laptop is my office.
- Lenovo finally stopped full APM support, most other vendors earlier.
- APM and SMP don't play well.
- APM and AMD64 don't play well either.
- Travelling around Germany drains the battery a lot.
Goals
- Suspend-to-RAM of a live system
- Manual disabling of unused devices
- Power-saving for inactive devices
- Inter-driver notification messages
PMF
- Device interface
- Event interface
Device interface of PMF
- Device power management in layers:
- Suspend: Class -> Device -> Bus
- Resume: Bus -> Device -> Class
- Handler failed -> whole transition cancelled
The PCI/Cardbus bus handling
- Suspend:
- Capture generic part of the configuration space
- Disable address decoding and bus mastering
- Transition to D3 state
- For Cardbus, optionally turn off power
- Resume:
- For cardbus, turn on power
- Transition to D0 state
- Restore generic part of the configuration space
- Shutdown:
- Disable address decoding and bus mastering
The network class handling
- Register passes down the associated interface
- Suspend calls if_stop
- Resume calls if_init and if_start if IFF_UP is set
- Logic to deactivate device if interface is down
- Enough for most network drivers
The audio class handling
- Exploits device tree to find physical device
- Suspend saves current mixer settings and stops play back / recording
- Resume restores mixer settings and restarts play back / recording
- Optional code to suspend audio device after 30 seconds
- Event handlers for volume up / down / toggle
System interface
- low: pmf_device_suspend and pmf_device_resume
- medium: pmf_device_recursive_suspend, pmf_device_recursive_resume,
pmf_device_resume_subtree
- high: pmf_system_suspend, pmf_system_resume, pmf_system_shutdown
Event interface
- Send event notifications to specific devices or the whole system
- Primary example: hot keys
- Pure userland solution too quirky
- Events are exposed via sysmon to userland
- Currently implemented:
- Lid open / close
- Volume up / down / toggle
- Display on / off / brighter / darker
ACPI infrastructure
- ACPI Component Architecture (ACPICA) was old, update needed
- ACPI Embedded Controller (EC) needed work for that
- ACPI Suspend-to-RAM support for AMD64 and SMP
ACPICA update (I)
- Many bug fixes in newer release from Intel
- Newer release not available from the Intel site, FreeBSD had them
- Many function signature changes
- New ACPICA showed locking issues in the EC driver
ACPICA update (II)
- ACPI Initialisation was difficult:
- Interrupt Routing tables not parsed when ACPI System Configuration Interrupt (SCI)
is set up
- Deferred Interrupt setup as workaround
- Split the initialisation:
- Just initialise the system enough to read the MADT
- Parse the MADT and prepare Interrupt Routing
- Finish the initialisation
ACPI EC rewrite (I)
- Used by ACPI Virtual Machine to access slow hardware
- Used to inform ACPI Virtual Machine about hardware events
- Very simple hardware protocol
ACPI EC rewrite (II)
ACPI EC rewrite (III)
- Two one-byte ports
- Query: Put reason for a SCI into the data buffer
- Read: Read address from data buffer and write current value back
- Write: Read address from data buffer followed by new value
- Enable burst: request attention from EC for back-to-back transfer
- Disable burst: release EC
ACPI EC rewrite (IV)
- Before:
- Mix of polling and interrupt mode
- Interleaved code paths
- Difficult to lock correctly
- After:
- Kernel thread for handling SCIs
- Read and write function as public interface
- Exclusive lock on the entry points
- State machine driven either by explicit polling or interrupts
ACPI EC rewrite (V)
ACPI EC rewrite (VI)
- Problems:
- Hardware doesn't polling in tight loop: 100ms delay from experiments
- Missing interrupts: schedule callout and just poll after a tick
- Robust driver and easily to add work arounds to
Existing Suspend-to-RAM support
- i386 only
- UP only
- APM or ACPI S3
Cleanup for ACPI S3 (I)
- setjmp/longjmp semantic and inline assembly harmful:
- Move register saving and restoring into acpi_md_sleep_prepare (asm)
- Suspend: acpi_md_sleep -> acpi_md_sleep_prepare -> acpi_md_sleep_enter
- Resume: acpi_md_sleep_exit -> acpi_md_sleep_prepare -> acpi_md_sleep
- Don't bother with callee-saved registers
Cleanup for ACPI S3 (II)
- KISS: hard wire addresses, ld can handle the offset
- KISS: copy page table and add identity mapping in the copy
- KISS: only initialize what is required
- ES, GS, SS or FS are not used early
- IDT can be loaded after using the real GDT
- GDT can be reloaded with the temporary GDT
- PSE must be enabled when page table contains such pages
— kernel code does
ACPI S3 on AMD64
- Bootstrap simplified as real mode is guaranteed to be under 4GB
- Two bootstrap:
- Move to Protect Mode without Paging
- Enable Long Mode
- Must restore No Executable Bit early (like PSE)
- Still very similar code
ACPI S3 on SMP
- Mark Application Processors (APs) as offline during device suspend
- Force FPU context switch on all CPUs.
- Registers are saved to cpu_info
- Inter-processor interrupt (IPI) for saving AP first
- Restart APs on resume individually
- Note: L1 cache flushes are core-local!
Video devices (I)
Video devices (II)
- Too many incompatible VGA chips
- Many don't have public specifications
- DRM modesetting and initialisation not usable (yet?)
Video devices (II)
- Some BIOSes turn on VGA (Thinkpads)
- Some can be tricked into by setting a BIOS password
- For some the Power On Self Test (POST) can be kicked on early
- Some just crash with that (Dell)
- Quo Vadis?
Video devices (II)
- Most systems works by forcing a VGA POST
- PCI bridges have to be reinitialised first
- Solution: Emulate the Real Mode and call the VGA BIOS
vbetool
- Works entirely in userland
- Either uses VM86 or software emulation
- Problems:
- Too late for debugging resume issues
- Needs access to physical memory and IO ports
libx86emu (I)
- Based on x86emu in vbetool and XFree86
- Allows early POST
- Problems:
- Increases kernel size
- VGA BIOS can crash kernel
libx86emu (II)
- Size: 80 KB on AMD64
- Allows emulation of specific devices, e.g. 8254 timers
- Allows panic from within X11 to reset the console
- Can be used for vesafb
Future work
- Processor sleep states (4% for C2, 8% for C3)
- Suspend of file systems
- Low power states for devices (esp. USB, Firewire)
- Suspend-to-disk