arm64电源管理之PSCI

PSCIPower State Coordination Interface功耗状态协同接口
SCPISystem Control and Power Interface系统控制和电源接口
SCMISystem Control and Management Interface系统控制和管理接口
SMCCCSMC Calling ConventionSMC调用约定

scpi;通过mailbox核间通信,如风扇,温度。。。
psci:调用smc。如开关机,cpu停止启动

PSCI控制cpu的行为,比如关核等。。系统的关机和启动。cpu的热插拔。

系统reboot系统调用:


kernel/reboot.c
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
		void __user *, arg)
{
	switch (cmd) {
	case LINUX_REBOOT_CMD_RESTART:
		kernel_restart(NULL);
		break;
	case LINUX_REBOOT_CMD_RESTART2:
		ret = strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1);
		if (ret < 0) {
			ret = -EFAULT;
			break;
		}
		buffer[sizeof(buffer) - 1] = '\0';

		kernel_restart(buffer);
		break;
	....
#ifdef CONFIG_KEXEC_CORE
	case LINUX_REBOOT_CMD_KEXEC:
		ret = kernel_kexec();
		break;
#endif

#ifdef CONFIG_HIBERNATION
	case LINUX_REBOOT_CMD_SW_SUSPEND:
		ret = hibernate();
		break;
#endif
}

 重启/reset调用kernel_restart:

//kernel/reboot.c
kernel_restart:
void kernel_restart(char *cmd)
{
	kernel_restart_prepare(cmd);
	migrate_to_reboot_cpu();
	syscore_shutdown();   
	if (!cmd)
		pr_emerg("Restarting system\n");
	else
		pr_emerg("Restarting system with command '%s'\n", cmd);
	kmsg_dump(KMSG_DUMP_SHUTDOWN);
	machine_restart(cmd);   //arch/arm64/kernel/process.c
}


//arch/arm64/kernel/process.c
void machine_restart(char *cmd)
{
	/* Disable interrupts first */
	local_irq_disable();
	smp_send_stop();

	/*
	 * UpdateCapsule() depends on the system being reset via
	 * ResetSystem().
	 */
	if (efi_enabled(EFI_RUNTIME_SERVICES))
		efi_reboot(reboot_mode, NULL);   //如果efi支持,则调用efi的runtime_services

	/* Now call the architecture specific reboot code. */
	if (arm_pm_restart)
		arm_pm_restart(reboot_mode, cmd);  //如果arm_pm_restart存在,这个定义在drivers/firmware/psci/psci.c
	else
		do_kernel_restart(cmd);

	/*
	 * Whoops - the architecture was unable to reboot.
	 */
	printk("Reboot failed -- System halted\n");
	while (1);
}

休眠调用hinernate: 



hibernate:
	power_down
		kernel_power_off()
			machine_power_off
					local_irq_disable();
					smp_send_stop();
					if (pm_power_off)
						pm_power_off();    //调用psci的函数psci_sys_poweroff
		kernel_halt();
		

上面一个调用arm_pm_restart和pm_power_off两个函数指针都在drivers/firmware/psci/psci.c中实现,同时也实现了psci_ops相关的函数,用来对cpu的控制:

static void __init psci_0_2_set_functions(void)
{
	pr_info("Using standard PSCI v0.2 function IDs\n");
	psci_ops.get_version = psci_get_version;

	psci_function_id[PSCI_FN_CPU_SUSPEND] =
					PSCI_FN_NATIVE(0_2, CPU_SUSPEND);
	psci_ops.cpu_suspend = psci_cpu_suspend;

	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
	psci_ops.cpu_off = psci_cpu_off;

	psci_function_id[PSCI_FN_CPU_ON] = PSCI_FN_NATIVE(0_2, CPU_ON);
	psci_ops.cpu_on = psci_cpu_on;

	psci_function_id[PSCI_FN_MIGRATE] = PSCI_FN_NATIVE(0_2, MIGRATE);
	psci_ops.migrate = psci_migrate;

	psci_ops.affinity_info = psci_affinity_info;

	psci_ops.migrate_info_type = psci_migrate_info_type;

	arm_pm_restart = psci_sys_reset;

	pm_power_off = psci_sys_poweroff;
}

比如 

static void psci_sys_poweroff(void){  invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);}

 PSCI_0_2_FN_SYSTEM_OFF的值计算为:0x84000000+8,在规范的表6-2:分配给不同服务的功能标识符的子范围中:

相关定义在include/uapi/linux/psci.h

SCPI: 

scpi是用来通过mailbox和其它核的通信,比如M核。

SoC就是System on Chip,一个芯片上集成了一个系统,一个系统往往有很多核,例如M核、A核、R核,以及异构的RISC-V核等,集成到一个芯片上的好处就是节省成本并且体积更小,能耗也更低,可谓是一举多得。但是多个核上的各种OS之间就需要进行通信,这也就是本文的主题:核间通信。核间通信也称为Mailbox,Mailbox技术是由软硬件协同实现的。

SoC软件技术--核间通信

TODO。比如风扇温度等。。 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古井无波 2024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值