forked from garasubo/T-Visor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
virtual_psci.c
59 lines (53 loc) · 1.32 KB
/
virtual_psci.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include "basic.h"
#include "type.h"
#include "virtual_psci.h"
#include "vcpu.h"
#include "vm.h"
#include "debug.h"
static UW virtual_psci_cpu_suspend(UW state, UW address, UW cid){
return PSCI_RET_NOT_SUPPORTED;
}
static UW virtual_psci_cpu_off(void){
vcpu_off(vcpu_get_executing());
return 0;
}
static UW virtual_psci_cpu_on(UW target, UW address, UW cid){
UW id = target & 0x3;
T_VM *vm = vcpu_get_executing()->vm;
if(id >= vm->vcpu_num){
tv_abort("id error\n");
return PSCI_RET_INVAL_ID_PARAMETERS;
}
T_VCPU *vcpu = &(vm->vcpus[id]);
if(vcpu->state!=VCPU_STATE_INIT){
return PSCI_RET_ALREADY_ON;
}
vcpu_reset(vcpu);
vcpu->reg[0] = cid;
vcpu->pc = address;
vcpu_ready(vcpu);
return 0;
}
UW virtual_psci(void)
{
tv_abort("psci call!\n");
UW* sp = vcpu_get_current_sp()->reg;
UW fid = sp[0];
UW ret = 0;
switch(fid){
case PSCI_FN_ID_CPU_SUSPEND:
ret = virtual_psci_cpu_suspend(sp[1], sp[2], sp[3]);
break;
case PSCI_FN_ID_CPU_OFF:
ret = virtual_psci_cpu_off();
break;
case PSCI_FN_ID_CPU_ON:
ret = virtual_psci_cpu_on(sp[1], sp[2], sp[3]);
break;
default:
ret = PSCI_RET_NOT_SUPPORTED;
tv_abort("unimplemented function!\n");
break;
}
return ret;
}