xref: /kvm-unit-tests/lib/arm/psci.c (revision 1742c67a722ef08d80f81cb13060d266d2cf69e3)
1 /*
2  * PSCI API
3  * From arch/arm[64]/kernel/psci.c
4  *
5  * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com>
6  *
7  * This work is licensed under the terms of the GNU LGPL, version 2.
8  */
9 #include <asm/psci.h>
10 #include <asm/setup.h>
11 #include <asm/page.h>
12 
13 #define T PSCI_INVOKE_ARG_TYPE
14 __attribute__((noinline))
15 int psci_invoke(T function_id, T arg0, T arg1, T arg2)
16 {
17 	asm volatile(
18 		"hvc #0"
19 	: "+r" (function_id)
20 	: "r" (arg0), "r" (arg1), "r" (arg2));
21 	return function_id;
22 }
23 
24 int psci_cpu_on(unsigned long cpuid, unsigned long entry_point)
25 {
26 	return psci_invoke(PSCI_FN_CPU_ON, cpuid, entry_point, 0);
27 }
28 
29 extern void secondary_entry(void);
30 int cpu_psci_cpu_boot(unsigned int cpu)
31 {
32 	int err = psci_cpu_on(cpus[cpu], __pa(secondary_entry));
33 	if (err)
34 		printf("failed to boot CPU%d (%d)\n", cpu, err);
35 	return err;
36 }
37 
38 #define PSCI_POWER_STATE_TYPE_POWER_DOWN (1U << 16)
39 void cpu_psci_cpu_die(unsigned int cpu)
40 {
41 	int err = psci_invoke(PSCI_0_2_FN_CPU_OFF,
42 			PSCI_POWER_STATE_TYPE_POWER_DOWN, 0, 0);
43 	printf("unable to power off CPU%d (%d)\n", cpu, err);
44 }
45 
46 void psci_sys_reset(void)
47 {
48 	psci_invoke(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
49 }
50