PSCI | Power State Coordination Interface | 功耗状态协同接口 |
SCPI | System Control and Power Interface | 系统控制和电源接口 |
SCMI | System Control and Management Interface | 系统控制和管理接口 |
SMCCC | SMC Calling Convention | SMC调用约定 |
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技术是由软硬件协同实现的。
TODO。比如风扇温度等。。