2 * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * This file is released under the GPLv2. See the COPYING file for more
14 static void __do_psw_swap(struct virt_cpu
*cpu
, u8
*gpsa
, u64 old
, u64
new,
17 memcpy(gpsa
+ old
, &cpu
->sie_cb
.gpsw
, len
);
18 memcpy(&cpu
->sie_cb
.gpsw
, gpsa
+ new, len
);
21 static int __io_int(struct virt_sys
*sys
)
23 struct virt_cpu
*cpu
= sys
->cpu
;
24 struct vio_int
*ioint
;
30 /* are I/O interrupts enabled? */
31 if (!cpu
->sie_cb
.gpsw
.io
)
34 cr6
= cpu
->sie_cb
.gcr
[6];
36 mutex_lock(&cpu
->int_lock
);
37 /* for each subclass, check that... */
39 /* ...the subclass is enabled */
40 if (!(cr6
& (0x80000000 >> i
)))
43 /* ...there are interrupts of that subclass */
44 if (list_empty(&cpu
->int_io
[i
]))
47 /* there is an interruption that we can perform */
48 ioint
= list_first_entry(&cpu
->int_io
[i
], struct vio_int
, list
);
49 list_del(&ioint
->list
);
51 mutex_unlock(&cpu
->int_lock
);
53 con_printf(sys
->con
, "Time for I/O int... isc:%d "
54 "%08x.%08x.%08x\n", i
, ioint
->ssid
,
55 ioint
->param
, ioint
->intid
);
57 /* get the guest's first page (PSA) */
58 ret
= virt2phy_current(0, &phy
);
60 con_printf(sys
->con
, "Failed to queue up I/O "
61 "interruption: %d (%s)\n", ret
,
63 cpu
->state
= GUEST_STOPPED
;
70 __do_psw_swap(cpu
, (void*) phy
, 0x170, 0x1f0, 16);
72 __do_psw_swap(cpu
, (void*) phy
, 56, 120, 8);
74 *((u32
*) (phy
+ 184)) = ioint
->ssid
;
75 *((u32
*) (phy
+ 188)) = ioint
->param
;
76 *((u32
*) (phy
+ 192)) = ioint
->intid
;
83 mutex_unlock(&cpu
->int_lock
);
87 void run_guest(struct virt_sys
*sys
)
89 struct psw
*psw
= &sys
->cpu
->sie_cb
.gpsw
;
96 if (!psw
->io
&& !psw
->ex
&& !psw
->m
) {
97 con_printf(sys
->con
, "ENTERED CP DUE TO DISABLED WAIT\n");
98 sys
->cpu
->state
= GUEST_STOPPED
;
108 FIXME("need to ->icptcode = 0;");
109 FIXME("load FPRs & FPCR");
112 * IMPORTANT: We MUST keep a valid stack address in R15. This way,
113 * if SIE gets interrupted via an interrupt in the host, the
114 * scheduler can still get to the struct task pointer on the stack
117 /* save current regs */
119 /* load the address of the guest state save area */
121 /* load the address of the reg save area */
123 /* load guest's R0-R13 */
127 /* save guest's R0-R13 */
128 " stmg 0,13,%2(14)\n"
129 /* restore all regs */
136 "J" (offsetof(struct virt_cpu
, regs
.gpr
)),
137 "J" (offsetof(struct virt_cpu
, sie_cb
))
142 FIXME("store FPRs & FPCR");
144 handle_interception(sys
);