Mercurial > hvf > hvf-old
view cp/guest/run.c @ 618:535aec703236
cp: define a FIXME macro that leaves a sclp message
There are far too many fixmes in the code. Sadly, the compiler simply
discards them. This usually isn't an issue until one accidentally hits a
"weird" bug which just turns out to be an unhandled (but documented) case in
another part of the code. Using a macro instead of a comment will let the
compiler string-ify the text, and then at runtime use SCLP to print it out.
This will immediatelly point at problem areas. So, keep an eye on SCLP from
now on :)
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Tue, 13 Dec 2011 22:20:50 -0500 |
parents | 31525cf0c76b |
children |
line wrap: on
line source
/* * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * This file is released under the GPLv2. See the COPYING file for more * details. */ #include <directory.h> #include <sched.h> #include <dat.h> #include <vcpu.h> #include <slab.h> static void __do_psw_swap(struct virt_cpu *cpu, u8 *gpsa, u64 old, u64 new, int len) { memcpy(gpsa + old, &cpu->sie_cb.gpsw, len); memcpy(&cpu->sie_cb.gpsw, gpsa + new, len); } static int __io_int(struct virt_sys *sys) { struct virt_cpu *cpu = sys->cpu; struct vio_int *ioint; u64 cr6; u64 phy; int ret; int i; /* are I/O interrupts enabled? */ if (!cpu->sie_cb.gpsw.io) return 0; cr6 = cpu->sie_cb.gcr[6]; mutex_lock(&cpu->int_lock); /* for each subclass, check that... */ for(i=0; i<8; i++) { /* ...the subclass is enabled */ if (!(cr6 & (0x80000000 >> i))) continue; /* ...there are interrupts of that subclass */ if (list_empty(&cpu->int_io[i])) continue; /* there is an interruption that we can perform */ ioint = list_first_entry(&cpu->int_io[i], struct vio_int, list); list_del(&ioint->list); mutex_unlock(&cpu->int_lock); con_printf(sys->con, "Time for I/O int... isc:%d " "%08x.%08x.%08x\n", i, ioint->ssid, ioint->param, ioint->intid); /* get the guest's first page (PSA) */ ret = virt2phy_current(0, &phy); if (ret) { con_printf(sys->con, "Failed to queue up I/O " "interruption: %d (%s)\n", ret, errstrings[-ret]); cpu->state = GUEST_STOPPED; return 0; } /* do the PSW swap */ if (VCPU_ZARCH(cpu)) __do_psw_swap(cpu, (void*) phy, 0x170, 0x1f0, 16); else __do_psw_swap(cpu, (void*) phy, 56, 120, 8); *((u32*) (phy + 184)) = ioint->ssid; *((u32*) (phy + 188)) = ioint->param; *((u32*) (phy + 192)) = ioint->intid; free(ioint); return 1; } mutex_unlock(&cpu->int_lock); return 0; } void run_guest(struct virt_sys *sys) { struct psw *psw = &sys->cpu->sie_cb.gpsw; u64 save_gpr[16]; if (__io_int(sys)) goto go; if (psw->w) { if (!psw->io && !psw->ex && !psw->m) { con_printf(sys->con, "ENTERED CP DUE TO DISABLED WAIT\n"); sys->cpu->state = GUEST_STOPPED; return; } /* wait state */ schedule(); return; } go: FIXME("need to ->icptcode = 0;"); FIXME("load FPRs & FPCR"); /* * IMPORTANT: We MUST keep a valid stack address in R15. This way, * if SIE gets interrupted via an interrupt in the host, the * scheduler can still get to the struct task pointer on the stack */ asm volatile( /* save current regs */ " stmg 0,15,%0\n" /* load the address of the guest state save area */ " lr 14,%1\n" /* load the address of the reg save area */ " la 15,%0\n" /* load guest's R0-R13 */ " lmg 0,13,%2(14)\n" /* SIE */ " sie %3(14)\n" /* save guest's R0-R13 */ " stmg 0,13,%2(14)\n" /* restore all regs */ " lmg 0,15,0(15)\n" : /* output */ "+m" (save_gpr) : /* input */ "a" (sys->cpu), "J" (offsetof(struct virt_cpu, regs.gpr)), "J" (offsetof(struct virt_cpu, sie_cb)) : /* clobbered */ "memory" ); FIXME("store FPRs & FPCR"); handle_interception(sys); }