diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2013-01-27 23:59:26 +0000 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-01-29 21:50:05 +0100 |
commit | 50c8d9bfc6d9ca48b978c6201f97bd850bd0dc83 (patch) | |
tree | 9a7fc2e9ac35cf8752e273dd17295c484c2ad50f | |
parent | 2e788490d83a4de5bea00207c8695edd5d487e4a (diff) |
s390: Use s390_cpu_physical_memory_map for tpi.
Map the I/O interruption code before calling into css.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r-- | hw/s390x/css.c | 2 | ||||
-rw-r--r-- | target-s390x/cpu.h | 4 | ||||
-rw-r--r-- | target-s390x/ioinst.c | 19 | ||||
-rw-r--r-- | target-s390x/ioinst.h | 7 |
4 files changed, 24 insertions, 8 deletions
diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 113ac9a893..84efd4ad87 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -852,7 +852,7 @@ int css_do_stcrw(CRW *crw) return ret; } -int css_do_tpi(uint64_t addr, int lowcore) +int css_do_tpi(IOIntCode *int_code, int lowcore) { /* No pending interrupts for !KVM. */ return 0; diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index ce12fa46bc..9be4a475a3 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -413,7 +413,7 @@ int css_do_hsch(SubchDev *sch); int css_do_ssch(SubchDev *sch, ORB *orb); int css_do_tsch(SubchDev *sch, IRB *irb); int css_do_stcrw(CRW *crw); -int css_do_tpi(uint64_t addr, int lowcore); +int css_do_tpi(IOIntCode *int_code, int lowcore); int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid, int rfmt, void *buf); void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo); @@ -471,7 +471,7 @@ static inline int css_do_stcrw(CRW *crw) { return 1; } -static inline int css_do_tpi(uint64_t addr, int lowcore) +static inline int css_do_tpi(IOIntCode *int_code, int lowcore) { return 0; } diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c index 4ef2d73a43..e3531f365e 100644 --- a/target-s390x/ioinst.c +++ b/target-s390x/ioinst.c @@ -619,16 +619,25 @@ int ioinst_handle_tpi(CPUS390XState *env, uint32_t ipb) { uint64_t addr; int lowcore; + IOIntCode *int_code; + hwaddr len, orig_len; + int ret; trace_ioinst("tpi"); addr = decode_basedisp_s(env, ipb); lowcore = addr ? 0 : 1; - if (addr < 8192) { - addr += env->psa; - } else if ((env->psa <= addr) && (addr < env->psa + 8192)) { - addr -= env->psa; + len = lowcore ? 8 /* two words */ : 12 /* three words */; + orig_len = len; + int_code = s390_cpu_physical_memory_map(env, addr, &len, 1); + if (!int_code || (len != orig_len)) { + program_interrupt(env, PGM_SPECIFICATION, 2); + ret = -EIO; + goto out; } - return css_do_tpi(addr, lowcore); + ret = css_do_tpi(int_code, lowcore); +out: + s390_cpu_physical_memory_unmap(env, int_code, len, 1); + return ret; } #define SCHM_REG1_RES(_reg) (_reg & 0x000000000ffffffc) diff --git a/target-s390x/ioinst.h b/target-s390x/ioinst.h index a59742c3c6..d5a43f4a71 100644 --- a/target-s390x/ioinst.h +++ b/target-s390x/ioinst.h @@ -195,6 +195,13 @@ typedef struct CRW { #define CRW_RSC_SUBCH 0x3 #define CRW_RSC_CHP 0x4 +/* I/O interruption code */ +typedef struct IOIntCode { + uint32_t subsys_id; + uint32_t intparm; + uint32_t interrupt_id; +} QEMU_PACKED IOIntCode; + /* schid disintegration */ #define IOINST_SCHID_ONE(_schid) ((_schid & 0x00010000) >> 16) #define IOINST_SCHID_M(_schid) ((_schid & 0x00080000) >> 19) |