xref: /kvmtool/arm/aarch32/kvm-cpu.c (revision fc9d8ec3e459b744c012b9c82924aa397099ab19)
1 #include "kvm/kvm-cpu.h"
2 #include "kvm/kvm.h"
3 #include "kvm/virtio.h"
4 
5 #include <asm/ptrace.h>
6 
7 #define ARM_CORE_REG(x)	(KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_CORE | \
8 			 KVM_REG_ARM_CORE_REG(x))
9 
10 #define ARM_CP15_REG_SHIFT_MASK(x,n)		\
11 	(((x) << KVM_REG_ARM_ ## n ## _SHIFT) & KVM_REG_ARM_ ## n ## _MASK)
12 
13 #define __ARM_CP15_REG(op1,crn,crm,op2)			\
14 	(KVM_REG_ARM | KVM_REG_SIZE_U32		|	\
15 	 (15 << KVM_REG_ARM_COPROC_SHIFT)	|	\
16 	 ARM_CP15_REG_SHIFT_MASK(op1, OPC1)	|	\
17 	 ARM_CP15_REG_SHIFT_MASK(crn, 32_CRN)	|	\
18 	 ARM_CP15_REG_SHIFT_MASK(crm, CRM)	|	\
19 	 ARM_CP15_REG_SHIFT_MASK(op2, 32_OPC2))
20 
21 #define ARM_CP15_REG(...)	__ARM_CP15_REG(__VA_ARGS__)
22 
23 unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu)
24 {
25 	struct kvm_one_reg reg;
26 	u32 mpidr;
27 
28 	reg.id = ARM_CP15_REG(ARM_CPU_ID, ARM_CPU_ID_MPIDR);
29 	reg.addr = (u64)(unsigned long)&mpidr;
30 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
31 		die("KVM_GET_ONE_REG failed (get_mpidr vcpu%ld", vcpu->cpu_id);
32 
33 	return mpidr;
34 }
35 
36 void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
37 {
38 	struct kvm *kvm	= vcpu->kvm;
39 	struct kvm_one_reg reg;
40 	u32 data;
41 
42 	/* Who said future-proofing was a good idea? */
43 	reg.addr = (u64)(unsigned long)&data;
44 
45 	/* cpsr = IRQs/FIQs masked */
46 	data	= PSR_I_BIT | PSR_F_BIT | SVC_MODE;
47 	reg.id	= ARM_CORE_REG(usr_regs.ARM_cpsr);
48 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
49 		die_perror("KVM_SET_ONE_REG failed (cpsr)");
50 
51 	/* Secondary cores are stopped awaiting PSCI wakeup */
52 	if (vcpu->cpu_id != 0)
53 		return;
54 
55 	/* r0 = 0 */
56 	data	= 0;
57 	reg.id	= ARM_CORE_REG(usr_regs.ARM_r0);
58 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
59 		die_perror("KVM_SET_ONE_REG failed (r0)");
60 
61 	/* r1 = machine type (-1) */
62 	data	= -1;
63 	reg.id	= ARM_CORE_REG(usr_regs.ARM_r1);
64 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
65 		die_perror("KVM_SET_ONE_REG failed (r1)");
66 
67 	/* r2 = physical address of the device tree blob */
68 	data	= kvm->arch.dtb_guest_start;
69 	reg.id	= ARM_CORE_REG(usr_regs.ARM_r2);
70 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
71 		die_perror("KVM_SET_ONE_REG failed (r2)");
72 
73 	/* pc = start of kernel image */
74 	data	= kvm->arch.kern_guest_start;
75 	reg.id	= ARM_CORE_REG(usr_regs.ARM_pc);
76 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
77 		die_perror("KVM_SET_ONE_REG failed (pc)");
78 }
79 
80 int kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
81 {
82 	struct kvm_one_reg reg;
83 	u32 data;
84 
85 	reg.id = ARM_CORE_REG(usr_regs.ARM_cpsr);
86 	reg.addr = (u64)(unsigned long)&data;
87 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
88 		die("KVM_GET_ONE_REG failed (cpsr)");
89 
90 	return (data & PSR_E_BIT) ? VIRTIO_ENDIAN_BE : VIRTIO_ENDIAN_LE;
91 }
92 
93 void kvm_cpu__show_code(struct kvm_cpu *vcpu)
94 {
95 	struct kvm_one_reg reg;
96 	u32 data;
97 	int debug_fd = kvm_cpu__get_debug_fd();
98 
99 	reg.addr = (u64)(unsigned long)&data;
100 
101 	dprintf(debug_fd, "\n*pc:\n");
102 	reg.id = ARM_CORE_REG(usr_regs.ARM_pc);
103 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
104 		die("KVM_GET_ONE_REG failed (show_code @ PC)");
105 
106 	kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
107 
108 	dprintf(debug_fd, "\n*lr (svc):\n");
109 	reg.id = ARM_CORE_REG(svc_regs[1]);
110 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
111 		die("KVM_GET_ONE_REG failed (show_code @ LR_svc)");
112 	data &= ~0x1;
113 
114 	kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
115 }
116 
117 void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
118 {
119 	struct kvm_one_reg reg;
120 	u32 data;
121 	int debug_fd = kvm_cpu__get_debug_fd();
122 
123 	reg.addr	= (u64)(unsigned long)&data;
124 	dprintf(debug_fd, "\n Registers:\n");
125 
126 	reg.id		= ARM_CORE_REG(usr_regs.ARM_pc);
127 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
128 		die("KVM_GET_ONE_REG failed (pc)");
129 	dprintf(debug_fd, " PC:    0x%x\n", data);
130 
131 	reg.id		= ARM_CORE_REG(usr_regs.ARM_cpsr);
132 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
133 		die("KVM_GET_ONE_REG failed (cpsr)");
134 	dprintf(debug_fd, " CPSR:  0x%x\n", data);
135 
136 	reg.id		= ARM_CORE_REG(svc_regs[0]);
137 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
138 		die("KVM_GET_ONE_REG failed (SP_svc)");
139 	dprintf(debug_fd, " SP_svc:  0x%x\n", data);
140 
141 	reg.id		= ARM_CORE_REG(svc_regs[1]);
142 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
143 		die("KVM_GET_ONE_REG failed (LR_svc)");
144 	dprintf(debug_fd, " LR_svc:  0x%x\n", data);
145 }
146