Revision ff9d2afa
b/hw/spapr.c | ||
---|---|---|
89 | 89 |
|
90 | 90 |
sPAPREnvironment *spapr; |
91 | 91 |
|
92 |
int spapr_allocate_irq(int hint, enum xics_irq_type type)
|
|
92 |
int spapr_allocate_irq(int hint, bool lsi)
|
|
93 | 93 |
{ |
94 | 94 |
int irq; |
95 | 95 |
|
... | ... | |
105 | 105 |
return 0; |
106 | 106 |
} |
107 | 107 |
|
108 |
xics_set_irq_type(spapr->icp, irq, type);
|
|
108 |
xics_set_irq_type(spapr->icp, irq, lsi);
|
|
109 | 109 |
|
110 | 110 |
return irq; |
111 | 111 |
} |
112 | 112 |
|
113 | 113 |
/* Allocate block of consequtive IRQs, returns a number of the first */ |
114 |
int spapr_allocate_irq_block(int num, enum xics_irq_type type)
|
|
114 |
int spapr_allocate_irq_block(int num, bool lsi)
|
|
115 | 115 |
{ |
116 | 116 |
int first = -1; |
117 | 117 |
int i; |
... | ... | |
119 | 119 |
for (i = 0; i < num; ++i) { |
120 | 120 |
int irq; |
121 | 121 |
|
122 |
irq = spapr_allocate_irq(0, type);
|
|
122 |
irq = spapr_allocate_irq(0, lsi);
|
|
123 | 123 |
if (!irq) { |
124 | 124 |
return -1; |
125 | 125 |
} |
b/hw/spapr.h | ||
---|---|---|
291 | 291 |
target_ulong spapr_hypercall(CPUPPCState *env, target_ulong opcode, |
292 | 292 |
target_ulong *args); |
293 | 293 |
|
294 |
int spapr_allocate_irq(int hint, enum xics_irq_type type);
|
|
295 |
int spapr_allocate_irq_block(int num, enum xics_irq_type type);
|
|
294 |
int spapr_allocate_irq(int hint, bool lsi);
|
|
295 |
int spapr_allocate_irq_block(int num, bool lsi);
|
|
296 | 296 |
|
297 | 297 |
static inline int spapr_allocate_msi(int hint) |
298 | 298 |
{ |
299 |
return spapr_allocate_irq(hint, XICS_MSI);
|
|
299 |
return spapr_allocate_irq(hint, false);
|
|
300 | 300 |
} |
301 | 301 |
|
302 | 302 |
static inline int spapr_allocate_lsi(int hint) |
303 | 303 |
{ |
304 |
return spapr_allocate_irq(hint, XICS_LSI);
|
|
304 |
return spapr_allocate_irq(hint, true);
|
|
305 | 305 |
} |
306 | 306 |
|
307 | 307 |
static inline uint32_t rtas_ld(target_ulong phys, int n) |
b/hw/spapr_pci.c | ||
---|---|---|
351 | 351 |
|
352 | 352 |
/* There is no cached config, allocate MSIs */ |
353 | 353 |
if (!phb->msi_table[ndev].nvec) { |
354 |
irq = spapr_allocate_irq_block(req_num, XICS_MSI);
|
|
354 |
irq = spapr_allocate_irq_block(req_num, true);
|
|
355 | 355 |
if (irq < 0) { |
356 | 356 |
fprintf(stderr, "Cannot allocate MSIs for device#%d", ndev); |
357 | 357 |
rtas_st(rets, 0, -1); /* Hardware error */ |
b/hw/xics.c | ||
---|---|---|
170 | 170 |
#define XICS_STATUS_REJECTED 0x4 |
171 | 171 |
#define XICS_STATUS_MASKED_PENDING 0x8 |
172 | 172 |
uint8_t status; |
173 |
enum xics_irq_type type;
|
|
173 |
bool lsi;
|
|
174 | 174 |
}; |
175 | 175 |
|
176 | 176 |
struct ics_state { |
... | ... | |
244 | 244 |
struct ics_state *ics = (struct ics_state *)opaque; |
245 | 245 |
struct ics_irq_state *irq = ics->irqs + srcno; |
246 | 246 |
|
247 |
if (irq->type == XICS_LSI) {
|
|
247 |
if (irq->lsi) {
|
|
248 | 248 |
set_irq_lsi(ics, srcno, val); |
249 | 249 |
} else { |
250 | 250 |
set_irq_msi(ics, srcno, val); |
... | ... | |
278 | 278 |
irq->server = server; |
279 | 279 |
irq->priority = priority; |
280 | 280 |
|
281 |
if (irq->type == XICS_LSI) {
|
|
281 |
if (irq->lsi) {
|
|
282 | 282 |
write_xive_lsi(ics, srcno); |
283 | 283 |
} else { |
284 | 284 |
write_xive_msi(ics, srcno); |
... | ... | |
301 | 301 |
struct ics_irq_state *irq = ics->irqs + i; |
302 | 302 |
|
303 | 303 |
/* FIXME: filter by server#? */ |
304 |
if (irq->type == XICS_LSI) {
|
|
304 |
if (irq->lsi) {
|
|
305 | 305 |
resend_lsi(ics, i); |
306 | 306 |
} else { |
307 | 307 |
resend_msi(ics, i); |
... | ... | |
314 | 314 |
int srcno = nr - ics->offset; |
315 | 315 |
struct ics_irq_state *irq = ics->irqs + srcno; |
316 | 316 |
|
317 |
if (irq->type == XICS_LSI) {
|
|
317 |
if (irq->lsi) {
|
|
318 | 318 |
irq->status &= ~XICS_STATUS_SENT; |
319 | 319 |
} |
320 | 320 |
} |
... | ... | |
333 | 333 |
return icp->ics->qirqs[irq - icp->ics->offset]; |
334 | 334 |
} |
335 | 335 |
|
336 |
void xics_set_irq_type(struct icp_state *icp, int irq, |
|
337 |
enum xics_irq_type type) |
|
336 |
void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi) |
|
338 | 337 |
{ |
339 | 338 |
assert((irq >= icp->ics->offset) |
340 | 339 |
&& (irq < (icp->ics->offset + icp->ics->nr_irqs))); |
341 |
assert((type == XICS_MSI) || (type == XICS_LSI)); |
|
342 | 340 |
|
343 |
icp->ics->irqs[irq - icp->ics->offset].type = type;
|
|
341 |
icp->ics->irqs[irq - icp->ics->offset].lsi = lsi;
|
|
344 | 342 |
} |
345 | 343 |
|
346 | 344 |
static target_ulong h_cppr(CPUPPCState *env, sPAPREnvironment *spapr, |
b/hw/xics.h | ||
---|---|---|
31 | 31 |
|
32 | 32 |
struct icp_state; |
33 | 33 |
|
34 |
enum xics_irq_type { |
|
35 |
XICS_MSI, /* Message-signalled (edge) interrupt */ |
|
36 |
XICS_LSI, /* Level-signalled interrupt */ |
|
37 |
}; |
|
38 |
|
|
39 | 34 |
qemu_irq xics_get_qirq(struct icp_state *icp, int irq); |
40 |
void xics_set_irq_type(struct icp_state *icp, int irq, |
|
41 |
enum xics_irq_type type); |
|
35 |
void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi); |
|
42 | 36 |
|
43 | 37 |
struct icp_state *xics_system_init(int nr_irqs); |
44 | 38 |
|
Also available in: Unified diff