build/ccw_gen: stat the file in C instead of shelling out
[hvf.git] / cp / guest / run.c
blob5eb2e27f800f2f504058cbeebab8ed71c1eddf04
1 /*
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
5 * details.
6 */
8 #include <directory.h>
9 #include <sched.h>
10 #include <dat.h>
11 #include <vcpu.h>
12 #include <slab.h>
14 static void __do_psw_swap(struct virt_cpu *cpu, u8 *gpsa, u64 old, u64 new,
15 int len)
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;
25 u64 cr6;
26 u64 phy;
27 int ret;
28 int i;
30 /* are I/O interrupts enabled? */
31 if (!cpu->sie_cb.gpsw.io)
32 return 0;
34 cr6 = cpu->sie_cb.gcr[6];
36 mutex_lock(&cpu->int_lock);
37 /* for each subclass, check that... */
38 for(i=0; i<8; i++) {
39 /* ...the subclass is enabled */
40 if (!(cr6 & (0x80000000 >> i)))
41 continue;
43 /* ...there are interrupts of that subclass */
44 if (list_empty(&cpu->int_io[i]))
45 continue;
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);
59 if (ret) {
60 con_printf(sys->con, "Failed to queue up I/O "
61 "interruption: %d (%s)\n", ret,
62 errstrings[-ret]);
63 cpu->state = GUEST_STOPPED;
65 return 0;
68 /* do the PSW swap */
69 if (VCPU_ZARCH(cpu))
70 __do_psw_swap(cpu, (void*) phy, 0x170, 0x1f0, 16);
71 else
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;
78 free(ioint);
80 return 1;
83 mutex_unlock(&cpu->int_lock);
84 return 0;
87 void run_guest(struct virt_sys *sys)
89 struct psw *psw = &sys->cpu->sie_cb.gpsw;
90 u64 save_gpr[16];
92 if (__io_int(sys))
93 goto go;
95 if (psw->w) {
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;
99 return;
102 /* wait state */
103 schedule();
104 return;
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
116 asm volatile(
117 /* save current regs */
118 " stmg 0,15,%0\n"
119 /* load the address of the guest state save area */
120 " lr 14,%1\n"
121 /* load the address of the reg save area */
122 " la 15,%0\n"
123 /* load guest's R0-R13 */
124 " lmg 0,13,%2(14)\n"
125 /* SIE */
126 " sie %3(14)\n"
127 /* save guest's R0-R13 */
128 " stmg 0,13,%2(14)\n"
129 /* restore all regs */
130 " lmg 0,15,0(15)\n"
132 : /* output */
133 "+m" (save_gpr)
134 : /* input */
135 "a" (sys->cpu),
136 "J" (offsetof(struct virt_cpu, regs.gpr)),
137 "J" (offsetof(struct virt_cpu, sie_cb))
138 : /* clobbered */
139 "memory"
142 FIXME("store FPRs & FPCR");
144 handle_interception(sys);