xref: /qemu/include/hw/ppc/xics.h (revision cc98c9fd5c17b8ab62ad91b183060d8f70b9d00d)
1  /*
2   * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
3   *
4   * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
5   *
6   * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
7   *
8   * Permission is hereby granted, free of charge, to any person obtaining a copy
9   * of this software and associated documentation files (the "Software"), to deal
10   * in the Software without restriction, including without limitation the rights
11   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12   * copies of the Software, and to permit persons to whom the Software is
13   * furnished to do so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in
16   * all copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21   * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24   * THE SOFTWARE.
25   *
26   */
27  
28  #ifndef XICS_H
29  #define XICS_H
30  
31  #include "exec/memory.h"
32  #include "hw/qdev-core.h"
33  #include "qom/object.h"
34  
35  #define XICS_IPI        0x2
36  #define XICS_BUID       0x1
37  #define XICS_IRQ_BASE   (XICS_BUID << 12)
38  
39  /*
40   * We currently only support one BUID which is our interrupt base
41   * (the kernel implementation supports more but we don't exploit
42   *  that yet)
43   */
44  typedef struct PnvICPState PnvICPState;
45  typedef struct ICSStateClass ICSStateClass;
46  typedef struct ICSState ICSState;
47  typedef struct ICSIRQState ICSIRQState;
48  typedef struct XICSFabric XICSFabric;
49  
50  #define TYPE_ICP "icp"
51  OBJECT_DECLARE_TYPE(ICPState, ICPStateClass,
52                      ICP)
53  
54  #define TYPE_PNV_ICP "pnv-icp"
55  DECLARE_INSTANCE_CHECKER(PnvICPState, PNV_ICP,
56                           TYPE_PNV_ICP)
57  
58  
59  struct ICPStateClass {
60      DeviceClass parent_class;
61  
62      DeviceRealize parent_realize;
63  };
64  
65  struct ICPState {
66      /*< private >*/
67      DeviceState parent_obj;
68      /*< public >*/
69      CPUState *cs;
70      ICSState *xirr_owner;
71      uint32_t xirr;
72      uint8_t pending_priority;
73      uint8_t mfrr;
74      qemu_irq output;
75  
76      XICSFabric *xics;
77  };
78  
79  #define ICP_PROP_XICS "xics"
80  #define ICP_PROP_CPU "cpu"
81  
82  struct PnvICPState {
83      ICPState parent_obj;
84  
85      MemoryRegion mmio;
86      uint32_t links[3];
87  };
88  
89  #define TYPE_ICS "ics"
90  DECLARE_OBJ_CHECKERS(ICSState, ICSStateClass,
91                       ICS, TYPE_ICS)
92  
93  
94  struct ICSStateClass {
95      DeviceClass parent_class;
96  
97      DeviceRealize parent_realize;
98      ResettablePhases parent_phases;
99  
100      void (*reject)(ICSState *s, uint32_t irq);
101      void (*resend)(ICSState *s);
102  };
103  
104  struct ICSState {
105      /*< private >*/
106      DeviceState parent_obj;
107      /*< public >*/
108      uint32_t nr_irqs;
109      uint32_t offset;
110      ICSIRQState *irqs;
111      XICSFabric *xics;
112  };
113  
114  #define ICS_PROP_XICS "xics"
115  
116  static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
117  {
118      return (nr >= ics->offset) && (nr < (ics->offset + ics->nr_irqs));
119  }
120  
121  struct ICSIRQState {
122      uint32_t server;
123      uint8_t priority;
124      uint8_t saved_priority;
125  #define XICS_STATUS_ASSERTED           0x1
126  #define XICS_STATUS_SENT               0x2
127  #define XICS_STATUS_REJECTED           0x4
128  #define XICS_STATUS_MASKED_PENDING     0x8
129  #define XICS_STATUS_PRESENTED          0x10
130  #define XICS_STATUS_QUEUED             0x20
131      uint8_t status;
132  /* (flags & XICS_FLAGS_IRQ_MASK) == 0 means the interrupt is not allocated */
133  #define XICS_FLAGS_IRQ_LSI             0x1
134  #define XICS_FLAGS_IRQ_MSI             0x2
135  #define XICS_FLAGS_IRQ_MASK            0x3
136      uint8_t flags;
137  };
138  
139  #define TYPE_XICS_FABRIC "xics-fabric"
140  #define XICS_FABRIC(obj)                                     \
141      INTERFACE_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
142  typedef struct XICSFabricClass XICSFabricClass;
143  DECLARE_CLASS_CHECKERS(XICSFabricClass, XICS_FABRIC,
144                         TYPE_XICS_FABRIC)
145  
146  struct XICSFabricClass {
147      InterfaceClass parent;
148      ICSState *(*ics_get)(XICSFabric *xi, int irq);
149      void (*ics_resend)(XICSFabric *xi);
150      ICPState *(*icp_get)(XICSFabric *xi, int server);
151  };
152  
153  ICPState *xics_icp_get(XICSFabric *xi, int server);
154  
155  /* Internal XICS interfaces */
156  void icp_set_cppr(ICPState *icp, uint8_t cppr);
157  void icp_set_mfrr(ICPState *icp, uint8_t mfrr);
158  uint32_t icp_accept(ICPState *ss);
159  uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr);
160  void icp_eoi(ICPState *icp, uint32_t xirr);
161  void icp_irq(ICSState *ics, int server, int nr, uint8_t priority);
162  void icp_reset(ICPState *icp);
163  
164  void ics_write_xive(ICSState *ics, int nr, int server,
165                      uint8_t priority, uint8_t saved_priority);
166  void ics_set_irq(void *opaque, int srcno, int val);
167  
168  static inline bool ics_irq_free(ICSState *ics, uint32_t srcno)
169  {
170      return !(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK);
171  }
172  
173  void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
174  void icp_pic_print_info(ICPState *icp, Monitor *mon);
175  void ics_pic_print_info(ICSState *ics, Monitor *mon);
176  
177  void ics_resend(ICSState *ics);
178  void icp_resend(ICPState *ss);
179  
180  Object *icp_create(Object *cpu, const char *type, XICSFabric *xi,
181                     Error **errp);
182  void icp_destroy(ICPState *icp);
183  
184  /* KVM */
185  void icp_get_kvm_state(ICPState *icp);
186  int icp_set_kvm_state(ICPState *icp, Error **errp);
187  void icp_synchronize_state(ICPState *icp);
188  void icp_kvm_realize(DeviceState *dev, Error **errp);
189  
190  void ics_get_kvm_state(ICSState *ics);
191  int ics_set_kvm_state_one(ICSState *ics, int srcno, Error **errp);
192  int ics_set_kvm_state(ICSState *ics, Error **errp);
193  void ics_synchronize_state(ICSState *ics);
194  void ics_kvm_set_irq(ICSState *ics, int srcno, int val);
195  
196  #endif /* XICS_H */
197