linux内核是如何支持深度睡眠(deep sleep)方式的?

摘要:
1.硬件架构arm642.内核版本4.193.分析相关函数setup_arch()-˃psci_dt_init()-˃psci_0_2_init()-˃get_set_conduit_method()-˃of_property_read_string(np,"method",&method))-˃set_conduit(PSCI_CONDUIT_HVC)或set_conduit(PSCI_COND

1. 硬件架构

arm64

2. 内核版本

4.19

3. 分析相关函数

setup_arch()

->psci_dt_init()

->psci_0_2_init()

-> get_set_conduit_method()

->of_property_read_string(np, "method", &method))

->set_conduit(PSCI_CONDUIT_HVC) 或set_conduit(PSCI_CONDUIT_SMC),根据设备树中的method属性来设定,

设定invoke_psci_fn回调函数(__invoke_psci_fn_smc或者__invoke_psci_fn_hvc)

->psci_probe()

__invoke_psci_fn_smc()

->arm_smccc_smc(),这是个宏定义,如下;

#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)

->__arm_smccc_smc(),定义在arch/arm64/kernel/smccc-call.S中:

.macro SMCCC instr
.cfi_startproc
instr #0
ldr x4, [sp]
stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
ldr x4, [sp, #8]
cbz x4, 1f /* no quirk structure */
ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6
b.ne 1f
str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
1: ret
.cfi_endproc
.endm

/*
* void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
* unsigned long a3, unsigned long a4, unsigned long a5,
* unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
* struct arm_smccc_quirk *quirk)
*/


ENTRY(__arm_smccc_smc)       SMCCC smc        ENDPROC(__arm_smccc_smc)

4. 相关变量

4.1 suspend_state_t mem_sleep_default = PM_SUSPEND_MAX; (kernel/power/suspend.c)

PM_SUSPEND_MAX的定义:   

#define PM_SUSPEND_MAX          ((__force suspend_state_t) 4)

所以默认mem_sleep_default = 4;

4.2suspend_state_t mem_sleep_current = PM_SUSPEND_TO_IDLE;   

PM_SUSPEND_TO_IDLE的定义:   

      #define PM_SUSPEND_TO_IDLE          ((__force suspend_state_t) 1)

所以默认mem_sleep_current = 1;

4.3 那么在哪里将mem_sleep_current的值改变了呢?

在suspend_set_ops()中改变了此值,调用路径如下:

psci_init_system_suspend()

->psci_features()

-> suspend_set_ops()

4.4 psci的版本号是从哪里获取的?

是从TF-A获取的

4.5 TF-A中psci固件的版本获取

相关代码在TF-A仓库的lib/psci/psci_main.c文件中     

    unsigned int psci_version(void)
    {
          return PSCI_MAJOR_VER |PSCI_MINOR_VER;
    }

调用路径如下:

psci_smc_handler()

-> psci_version()

免责声明:文章转载自《linux内核是如何支持深度睡眠(deep sleep)方式的?》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Hive的安装与部署(MySQL作为元数据库)OpenGL编程逐步深入(四)Shaders下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux中RTX和QQ安装

系统版本:Linux Ubuntu12.10-x64 安装步骤: 1.打开软件中心搜索Wine并安装。 2.打开软件中心搜索Winetricks并安装。 3.将winetricks中的内容覆盖/home/zhaojian/.cache/winetricks中的东东。 3.安装windows依赖包: 1 baekmuk colorprofile consol...

安装cfssl证书工具

安装版本 cfssl 1.2 https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 下载安装包 wget http...

Linux FTP基本操作命令 ( 序列二 ftp)

1.登陆ftp服务器 ftp [IP] [PORT] # 登陆ftp服务器,本机登陆可以不写IP实例: [root@ftpsrv vsftpd]#ftp 127.0.0.1 21 Connected to 127.0.0.1 (127.0.0.1). (vsFTPd 2.2.2) Name (127.0.0.1:root): nice Ple...

linux 头文件

在不同版本的内核源码上,头文件所在的位置是不同的,比如说在 #include<asm/arch/regs-gpio.h> #include<mach/regs-gpio.h> 同样是regs-gpio.h,<asm/arch/regs-gpio.h>是在比较低的版本(比如2.6.25)上位于arch/arm/includ...

linux为 rsync 添加开机启动

[root@rsync-server-1 /]# echo "/usr/bin/rsync --daemon" >> /etc/rc.local [root@rsync-server-1 /]# grep daemon /etc/rc.local # rsyncd service daemon by sun 20140628 /usr/bin/...

Linux监控分析

一、linux硬件 CPU(计算、逻辑判断、逻辑处理)、内存(cpu在内存中处理数据(记忆片段))、IO(对磁盘在一段时间内的读写操作) cpu和内存间有块区域缓存(二级缓存) cpu高:检查cpu,查看系统的瓶颈点是否在cpu上,看cpu把时间花费在哪个地方了,如果说,在这过程中,cup没有浪费时间,只能加cpu;如果cpu确实有浪费时间的地方,解决这个...