我用 LinuxLinux学习之路Linux

Linux PSCI框架

2019-07-11  本文已影响2人  Loyen

背景

说明:

  1. Kernel版本:4.14
  2. ARM64处理器
  3. 使用工具:Source Insight 3.5, Visio

1. 介绍

PSCI, Power State Coordination Interface,由ARM定义的电源管理接口规范,通常由Firmware来实现,而Linux系统可以通过smc/hvc指令来进入不同的Exception Level,进而调用对应的实现。

那问题来了?为什么要把这个放到Firmware中去实现呢?原因是ARMv8架构,引入了Virtualization,Security等概念,CPU boot、shutdown、suspend/resumen等操作不再如传统那样单纯了。我们不再是我们,我们依然是我们。

2. 分析

代码路径:
arch/arm64/kernel/psci.c
drivers/firmware/psci.c

2.1 总体框架

Linux对CPU core的操作抽象出了结构struct cpu_operations,开放给上层软件调用,struct cpu_operations统一对底层的CPU及power等资源进行统一操作,完美。
今天我们的故事就从struct cpu_operations开始。

话不多说,直接上图分析吧


所以,现在看起来PSCI其实就是去实现调用底层Firmware的接口,并且填充到对应的数据结构中就行了。

目前在内核中有三个版本的PSCI,分别是:PSCI V0.1/, PSCI V0.2/, PSCI V1.0,对应的psci_of_match[]一目了然:

static const struct of_device_id psci_of_match[] __initconst = {
    { .compatible = "arm,psci", .data = psci_0_1_init},
    { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
    { .compatible = "arm,psci-1.0", .data = psci_0_2_init},
    {},
};

2.1 PSCI v0.1分析

下边分析下PSCI v0.1吧

我们从哪里来?要到哪里去?老规矩,直接上图:


那么如何从Device Tree到实际的解析和配置中来的呢?
下面以arch/arm/boot/dts/xenvm-4.2.dts为例:

2.2 PSCI v0.2及以上与PSCI v0.1的区别


Case 1: PSCI v0.1 only.

        psci {
                compatible      = "arm,psci";
                method          = "smc";
                cpu_suspend     = <0x95c10000>;
                cpu_off         = <0x95c10001>;
                cpu_on          = <0x95c10002>;
                migrate         = <0x95c10003>;
        };

Case 2: PSCI v0.2 only

        psci {
                compatible      = "arm,psci-0.2";
                method          = "smc";
        };

Case 3: PSCI v0.2 and PSCI v0.1.

        A DTB may provide IDs for use by kernels without PSCI 0.2 support,
        enabling firmware and hypervisors to support existing and new kernels.
        These IDs will be ignored by kernels with PSCI 0.2 support, which will
        use the standard PSCI 0.2 IDs exclusively.

        psci {
                compatible = "arm,psci-0.2", "arm,psci";
                method = "hvc";

                cpu_on = < arbitrary value >;
                cpu_off = < arbitrary value >;

                ...
        };

说了是框架分析,不指望贴代码了,收工。

PS:

后续我将持续分析Linux Kernel中的子模块,尽量采取图文并茂的方式。It will be a good journey!
最近打算把文章同步到微信公众号平台去,欢迎大家关注,共同成长。


公众号
上一篇 下一篇

猜你喜欢

热点阅读