2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 * Copyright IBM Corp. 2008
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
20 #include <linux/kvm_host.h>
21 #include <linux/err.h>
24 #include <asm/cputable.h>
25 #include <asm/tlbflush.h>
26 #include <asm/kvm_44x.h>
27 #include <asm/kvm_ppc.h>
31 /* Note: clearing MSR[DE] just means that the debug interrupt will not be
32 * delivered *immediately*. Instead, it simply sets the appropriate DBSR bits.
33 * If those DBSR bits are still set when MSR[DE] is re-enabled, the interrupt
34 * will be delivered as an "imprecise debug event" (which is indicated by
37 static void kvm44x_disable_debug_interrupts(void)
39 mtmsr(mfmsr() & ~MSR_DE
);
42 void kvmppc_core_load_host_debugstate(struct kvm_vcpu
*vcpu
)
44 kvm44x_disable_debug_interrupts();
46 mtspr(SPRN_IAC1
, vcpu
->arch
.host_iac
[0]);
47 mtspr(SPRN_IAC2
, vcpu
->arch
.host_iac
[1]);
48 mtspr(SPRN_IAC3
, vcpu
->arch
.host_iac
[2]);
49 mtspr(SPRN_IAC4
, vcpu
->arch
.host_iac
[3]);
50 mtspr(SPRN_DBCR1
, vcpu
->arch
.host_dbcr1
);
51 mtspr(SPRN_DBCR2
, vcpu
->arch
.host_dbcr2
);
52 mtspr(SPRN_DBCR0
, vcpu
->arch
.host_dbcr0
);
53 mtmsr(vcpu
->arch
.host_msr
);
56 void kvmppc_core_load_guest_debugstate(struct kvm_vcpu
*vcpu
)
58 struct kvm_guest_debug
*dbg
= &vcpu
->guest_debug
;
61 vcpu
->arch
.host_msr
= mfmsr();
62 kvm44x_disable_debug_interrupts();
64 /* Save host debug register state. */
65 vcpu
->arch
.host_iac
[0] = mfspr(SPRN_IAC1
);
66 vcpu
->arch
.host_iac
[1] = mfspr(SPRN_IAC2
);
67 vcpu
->arch
.host_iac
[2] = mfspr(SPRN_IAC3
);
68 vcpu
->arch
.host_iac
[3] = mfspr(SPRN_IAC4
);
69 vcpu
->arch
.host_dbcr0
= mfspr(SPRN_DBCR0
);
70 vcpu
->arch
.host_dbcr1
= mfspr(SPRN_DBCR1
);
71 vcpu
->arch
.host_dbcr2
= mfspr(SPRN_DBCR2
);
73 /* set registers up for guest */
76 mtspr(SPRN_IAC1
, dbg
->bp
[0]);
77 dbcr0
|= DBCR0_IAC1
| DBCR0_IDM
;
80 mtspr(SPRN_IAC2
, dbg
->bp
[1]);
81 dbcr0
|= DBCR0_IAC2
| DBCR0_IDM
;
84 mtspr(SPRN_IAC3
, dbg
->bp
[2]);
85 dbcr0
|= DBCR0_IAC3
| DBCR0_IDM
;
88 mtspr(SPRN_IAC4
, dbg
->bp
[3]);
89 dbcr0
|= DBCR0_IAC4
| DBCR0_IDM
;
92 mtspr(SPRN_DBCR0
, dbcr0
);
97 void kvmppc_core_vcpu_load(struct kvm_vcpu
*vcpu
, int cpu
)
99 kvmppc_44x_tlb_load(vcpu
);
102 void kvmppc_core_vcpu_put(struct kvm_vcpu
*vcpu
)
104 kvmppc_44x_tlb_put(vcpu
);
107 int kvmppc_core_check_processor_compat(void)
111 if (strcmp(cur_cpu_spec
->platform
, "ppc440") == 0)
119 int kvmppc_core_vcpu_setup(struct kvm_vcpu
*vcpu
)
121 struct kvmppc_vcpu_44x
*vcpu_44x
= to_44x(vcpu
);
122 struct kvmppc_44x_tlbe
*tlbe
= &vcpu_44x
->guest_tlb
[0];
126 tlbe
->word0
= PPC44x_TLB_16M
| PPC44x_TLB_VALID
;
128 tlbe
->word2
= PPC44x_TLB_SX
| PPC44x_TLB_SW
| PPC44x_TLB_SR
;
132 tlbe
->word0
= 0xef600000 | PPC44x_TLB_4K
| PPC44x_TLB_VALID
;
133 tlbe
->word1
= 0xef600000;
134 tlbe
->word2
= PPC44x_TLB_SX
| PPC44x_TLB_SW
| PPC44x_TLB_SR
135 | PPC44x_TLB_I
| PPC44x_TLB_G
;
137 /* Since the guest can directly access the timebase, it must know the
138 * real timebase frequency. Accordingly, it must see the state of
140 vcpu
->arch
.ccr1
= mfspr(SPRN_CCR1
);
142 for (i
= 0; i
< ARRAY_SIZE(vcpu_44x
->shadow_refs
); i
++)
143 vcpu_44x
->shadow_refs
[i
].gtlb_index
= -1;
148 /* 'linear_address' is actually an encoding of AS|PID|EADDR . */
149 int kvmppc_core_vcpu_translate(struct kvm_vcpu
*vcpu
,
150 struct kvm_translation
*tr
)
152 struct kvmppc_vcpu_44x
*vcpu_44x
= to_44x(vcpu
);
153 struct kvmppc_44x_tlbe
*gtlbe
;
159 eaddr
= tr
->linear_address
;
160 pid
= (tr
->linear_address
>> 32) & 0xff;
161 as
= (tr
->linear_address
>> 40) & 0x1;
163 index
= kvmppc_44x_tlb_index(vcpu
, eaddr
, pid
, as
);
169 gtlbe
= &vcpu_44x
->guest_tlb
[index
];
171 tr
->physical_address
= tlb_xlate(gtlbe
, eaddr
);
172 /* XXX what does "writeable" and "usermode" even mean? */
178 struct kvm_vcpu
*kvmppc_core_vcpu_create(struct kvm
*kvm
, unsigned int id
)
180 struct kvmppc_vcpu_44x
*vcpu_44x
;
181 struct kvm_vcpu
*vcpu
;
184 vcpu_44x
= kmem_cache_zalloc(kvm_vcpu_cache
, GFP_KERNEL
);
190 vcpu
= &vcpu_44x
->vcpu
;
191 err
= kvm_vcpu_init(vcpu
, kvm
, id
);
198 kmem_cache_free(kvm_vcpu_cache
, vcpu_44x
);
203 void kvmppc_core_vcpu_free(struct kvm_vcpu
*vcpu
)
205 struct kvmppc_vcpu_44x
*vcpu_44x
= to_44x(vcpu
);
207 kvm_vcpu_uninit(vcpu
);
208 kmem_cache_free(kvm_vcpu_cache
, vcpu_44x
);
211 static int kvmppc_44x_init(void)
215 r
= kvmppc_booke_init();
219 return kvm_init(NULL
, sizeof(struct kvmppc_vcpu_44x
), THIS_MODULE
);
222 static void kvmppc_44x_exit(void)
227 module_init(kvmppc_44x_init
);
228 module_exit(kvmppc_44x_exit
);