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
->task
->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
);
89 * - issue any pending interruptions
91 void run_guest(struct virt_sys
*sys
)
93 struct psw
*psw
= &sys
->task
->cpu
->sie_cb
.gpsw
;
100 if (!psw
->io
&& !psw
->ex
&& !psw
->m
) {
101 con_printf(sys
->con
, "ENTERED CP DUE TO DISABLED WAIT\n");
102 sys
->task
->cpu
->state
= GUEST_STOPPED
;
113 * FIXME: need to ->icptcode = 0;
117 * FIXME: load FPRs & FPCR
121 * IMPORTANT: We MUST keep a valid stack address in R15. This way,
122 * if SIE gets interrupted via an interrupt in the host, the
123 * scheduler can still get to the struct task pointer on the stack
126 /* save current regs */
128 /* load the address of the guest state save area */
130 /* load the address of the reg save area */
132 /* load guest's R0-R13 */
136 /* save guest's R0-R13 */
137 " stmg 0,13,%2(14)\n"
138 /* restore all regs */
144 "a" (sys
->task
->cpu
),
145 "J" (offsetof(struct virt_cpu
, regs
.gpr
)),
146 "J" (offsetof(struct virt_cpu
, sie_cb
))
152 * FIXME: store FPRs & FPCR
155 handle_interception(sys
);