~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to target-s390x/interrupt.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * QEMU S/390 Interrupt support
3
 
 *
4
 
 * Copyright IBM Corp. 2012, 2014
5
 
 *
6
 
 * This work is licensed under the terms of the GNU GPL, version 2 or (at your
7
 
 * option) any later version.  See the COPYING file in the top-level directory.
8
 
 */
9
 
 
10
 
#include "qemu/osdep.h"
11
 
#include "cpu.h"
12
 
#include "sysemu/kvm.h"
13
 
#include "hw/s390x/ioinst.h"
14
 
 
15
 
#if !defined(CONFIG_USER_ONLY)
16
 
void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param,
17
 
                    uint64_t param64)
18
 
{
19
 
    CPUS390XState *env = &cpu->env;
20
 
 
21
 
    if (env->ext_index == MAX_EXT_QUEUE - 1) {
22
 
        /* ugh - can't queue anymore. Let's drop. */
23
 
        return;
24
 
    }
25
 
 
26
 
    env->ext_index++;
27
 
    assert(env->ext_index < MAX_EXT_QUEUE);
28
 
 
29
 
    env->ext_queue[env->ext_index].code = code;
30
 
    env->ext_queue[env->ext_index].param = param;
31
 
    env->ext_queue[env->ext_index].param64 = param64;
32
 
 
33
 
    env->pending_int |= INTERRUPT_EXT;
34
 
    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
35
 
}
36
 
 
37
 
static void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id,
38
 
                          uint16_t subchannel_number,
39
 
                          uint32_t io_int_parm, uint32_t io_int_word)
40
 
{
41
 
    CPUS390XState *env = &cpu->env;
42
 
    int isc = IO_INT_WORD_ISC(io_int_word);
43
 
 
44
 
    if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
45
 
        /* ugh - can't queue anymore. Let's drop. */
46
 
        return;
47
 
    }
48
 
 
49
 
    env->io_index[isc]++;
50
 
    assert(env->io_index[isc] < MAX_IO_QUEUE);
51
 
 
52
 
    env->io_queue[env->io_index[isc]][isc].id = subchannel_id;
53
 
    env->io_queue[env->io_index[isc]][isc].nr = subchannel_number;
54
 
    env->io_queue[env->io_index[isc]][isc].parm = io_int_parm;
55
 
    env->io_queue[env->io_index[isc]][isc].word = io_int_word;
56
 
 
57
 
    env->pending_int |= INTERRUPT_IO;
58
 
    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
59
 
}
60
 
 
61
 
static void cpu_inject_crw_mchk(S390CPU *cpu)
62
 
{
63
 
    CPUS390XState *env = &cpu->env;
64
 
 
65
 
    if (env->mchk_index == MAX_MCHK_QUEUE - 1) {
66
 
        /* ugh - can't queue anymore. Let's drop. */
67
 
        return;
68
 
    }
69
 
 
70
 
    env->mchk_index++;
71
 
    assert(env->mchk_index < MAX_MCHK_QUEUE);
72
 
 
73
 
    env->mchk_queue[env->mchk_index].type = 1;
74
 
 
75
 
    env->pending_int |= INTERRUPT_MCHK;
76
 
    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
77
 
}
78
 
 
79
 
/*
80
 
 * All of the following interrupts are floating, i.e. not per-vcpu.
81
 
 * We just need a dummy cpustate in order to be able to inject in the
82
 
 * non-kvm case.
83
 
 */
84
 
void s390_sclp_extint(uint32_t parm)
85
 
{
86
 
    if (kvm_enabled()) {
87
 
        kvm_s390_service_interrupt(parm);
88
 
    } else {
89
 
        S390CPU *dummy_cpu = s390_cpu_addr2state(0);
90
 
 
91
 
        cpu_inject_ext(dummy_cpu, EXT_SERVICE, parm, 0);
92
 
    }
93
 
}
94
 
 
95
 
void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
96
 
                       uint32_t io_int_parm, uint32_t io_int_word)
97
 
{
98
 
    if (kvm_enabled()) {
99
 
        kvm_s390_io_interrupt(subchannel_id, subchannel_nr, io_int_parm,
100
 
                              io_int_word);
101
 
    } else {
102
 
        S390CPU *dummy_cpu = s390_cpu_addr2state(0);
103
 
 
104
 
        cpu_inject_io(dummy_cpu, subchannel_id, subchannel_nr, io_int_parm,
105
 
                      io_int_word);
106
 
    }
107
 
}
108
 
 
109
 
void s390_crw_mchk(void)
110
 
{
111
 
    if (kvm_enabled()) {
112
 
        kvm_s390_crw_mchk();
113
 
    } else {
114
 
        S390CPU *dummy_cpu = s390_cpu_addr2state(0);
115
 
 
116
 
        cpu_inject_crw_mchk(dummy_cpu);
117
 
    }
118
 
}
119
 
 
120
 
#endif