• Lorenzo Pieralisi's avatar
    arm64: kernel: cpu_{suspend/resume} implementation · 95322526
    Lorenzo Pieralisi authored
    Kernel subsystems like CPU idle and suspend to RAM require a generic
    mechanism to suspend a processor, save its context and put it into
    a quiescent state. The cpu_{suspend}/{resume} implementation provides
    such a framework through a kernel interface allowing to save/restore
    registers, flush the context to DRAM and suspend/resume to/from
    low-power states where processor context may be lost.
    
    The CPU suspend implementation relies on the suspend protocol registered
    in CPU operations to carry out a suspend request after context is
    saved and flushed to DRAM. The cpu_suspend interface:
    
    int cpu_suspend(unsigned long arg);
    
    allows to pass an opaque parameter that is handed over to the suspend CPU
    operations back-end so that it can take action according to the
    semantics attached to it. The arg parameter allows suspend to RAM and CPU
    idle drivers to communicate to suspend protocol back-ends; it requires
    standardization so that the interface can be reused seamlessly across
    systems, paving the way for generic drivers.
    
    Context memory is allocated on the stack, whose address is stashed in a
    per-cpu variable to keep track of it and passed to core functions that
    save/restore the registers required by the architecture.
    
    Even though, upon successful execution, the cpu_suspend function shuts
    down the suspending processor, the warm boot resume mechanism, based
    on the cpu_resume function, makes the resume path operate as a
    cpu_suspend function return, so that cpu_suspend can be treated as a C
    function by the caller, which simplifies coding the PM drivers that rely
    on the cpu_suspend API.
    
    Upon context save, the minimal amount of memory is flushed to DRAM so
    that it can be retrieved when the MMU is off and caches are not searched.
    
    The suspend CPU operation, depending on the required operations (eg CPU vs
    Cluster shutdown) is in charge of flushing the cache hierarchy either
    implicitly (by calling firmware implementations like PSCI) or explicitly
    by executing the required cache maintainance functions.
    
    Debug exceptions are disabled during cpu_{suspend}/{resume} operations
    so that debug registers can be saved and restored properly preventing
    preemption from debug agents enabled in the kernel.
    Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
    95322526
suspend.c 2.92 KB