[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH 11/23] spapr: split the IRQ allocation sequence
From: |
David Gibson |
Subject: |
[Qemu-ppc] [PATCH 11/23] spapr: split the IRQ allocation sequence |
Date: |
Fri, 22 Jun 2018 14:24:25 +1000 |
From: Cédric Le Goater <address@hidden>
Today, when a device requests for IRQ number in a sPAPR machine, the
spapr_irq_alloc() routine first scans the ICSState status array to
find an empty slot and then performs the assignement of the selected
numbers. Split this sequence in two distinct routines : spapr_irq_find()
for lookups and spapr_irq_claim() for claiming the IRQ numbers.
This will ease the introduction of a static layout of IRQ numbers.
Signed-off-by: Cédric Le Goater <address@hidden>
Signed-off-by: David Gibson <address@hidden>
---
hw/ppc/spapr.c | 50 ++++++++++++++++++++++++++++++++++++++++++
hw/ppc/spapr_events.c | 18 +++++++++++----
hw/ppc/spapr_pci.c | 23 ++++++++++++++++---
hw/ppc/spapr_vio.c | 10 ++++++++-
include/hw/ppc/spapr.h | 4 ++++
5 files changed, 97 insertions(+), 8 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4a0b679166..b7705c3944 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3816,6 +3816,36 @@ static int ics_find_free_block(ICSState *ics, int num,
int alignnum)
return -1;
}
+int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp)
+{
+ ICSState *ics = spapr->ics;
+ int first = -1;
+
+ assert(ics);
+
+ /*
+ * MSIMesage::data is used for storing VIRQ so
+ * it has to be aligned to num to support multiple
+ * MSI vectors. MSI-X is not affected by this.
+ * The hint is used for the first IRQ, the rest should
+ * be allocated continuously.
+ */
+ if (align) {
+ assert((num == 1) || (num == 2) || (num == 4) ||
+ (num == 8) || (num == 16) || (num == 32));
+ first = ics_find_free_block(ics, num, num);
+ } else {
+ first = ics_find_free_block(ics, num, 1);
+ }
+
+ if (first < 0) {
+ error_setg(errp, "can't find a free %d-IRQ block", num);
+ return -1;
+ }
+
+ return first + ics->offset;
+}
+
/*
* Allocate the IRQ number and set the IRQ type, LSI or MSI
*/
@@ -3894,6 +3924,26 @@ int spapr_irq_alloc_block(sPAPRMachineState *spapr, int
num, bool lsi,
return first;
}
+int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp)
+{
+ ICSState *ics = spapr->ics;
+
+ assert(ics);
+
+ if (!ics_valid_irq(ics, irq)) {
+ error_setg(errp, "IRQ %d is invalid", irq);
+ return -1;
+ }
+
+ if (!ICS_IRQ_FREE(ics, irq - ics->offset)) {
+ error_setg(errp, "IRQ %d is not free", irq);
+ return -1;
+ }
+
+ spapr_irq_set_lsi(spapr, irq, lsi);
+ return 0;
+}
+
void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num)
{
ICSState *ics = spapr->ics;
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 86836f0626..e4f5946a21 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -707,13 +707,18 @@ void spapr_clear_pending_events(sPAPRMachineState *spapr)
void spapr_events_init(sPAPRMachineState *spapr)
{
+ int epow_irq;
+
+ epow_irq = spapr_irq_findone(spapr, &error_fatal);
+
+ spapr_irq_claim(spapr, epow_irq, false, &error_fatal);
+
QTAILQ_INIT(&spapr->pending_events);
spapr->event_sources = spapr_event_sources_new();
spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_EPOW,
- spapr_irq_alloc(spapr, 0, false,
- &error_fatal));
+ epow_irq);
/* NOTE: if machine supports modern/dedicated hotplug event source,
* we add it to the device-tree unconditionally. This means we may
@@ -724,9 +729,14 @@ void spapr_events_init(sPAPRMachineState *spapr)
* checking that it's enabled.
*/
if (spapr->use_hotplug_event_source) {
+ int hp_irq;
+
+ hp_irq = spapr_irq_findone(spapr, &error_fatal);
+
+ spapr_irq_claim(spapr, hp_irq, false, &error_fatal);
+
spapr_event_sources_register(spapr->event_sources,
EVENT_CLASS_HOT_PLUG,
- spapr_irq_alloc(spapr, 0, false,
- &error_fatal));
+ hp_irq);
}
spapr->epow_notifier.notify = spapr_powerdown_req;
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index f936ce63ef..497b896c7d 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -279,6 +279,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
spapr_pci_msi *msi;
int *config_addr_key;
Error *err = NULL;
+ int i;
/* Fins sPAPRPHBState */
phb = spapr_pci_find_phb(spapr, buid);
@@ -371,8 +372,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
}
/* Allocate MSIs */
- irq = spapr_irq_alloc_block(spapr, req_num, false,
- ret_intr_type == RTAS_TYPE_MSI, &err);
+ irq = spapr_irq_find(spapr, req_num, ret_intr_type == RTAS_TYPE_MSI, &err);
if (err) {
error_reportf_err(err, "Can't allocate MSIs for device %x: ",
config_addr);
@@ -380,6 +380,16 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
return;
}
+ for (i = 0; i < req_num; i++) {
+ spapr_irq_claim(spapr, irq + i, false, &err);
+ if (err) {
+ error_reportf_err(err, "Can't allocate MSIs for device %x: ",
+ config_addr);
+ rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
+ return;
+ }
+ }
+
/* Release previous MSIs */
if (msi) {
spapr_irq_free(spapr, msi->first_irq, msi->num);
@@ -1698,7 +1708,14 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
uint32_t irq;
Error *local_err = NULL;
- irq = spapr_irq_alloc_block(spapr, 1, true, false, &local_err);
+ irq = spapr_irq_findone(spapr, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ error_prepend(errp, "can't allocate LSIs: ");
+ return;
+ }
+
+ spapr_irq_claim(spapr, irq, true, &local_err);
if (local_err) {
error_propagate(errp, local_err);
error_prepend(errp, "can't allocate LSIs: ");
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 4555c648a8..daf85130b5 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -475,7 +475,15 @@ static void spapr_vio_busdev_realize(DeviceState *qdev,
Error **errp)
dev->qdev.id = id;
}
- dev->irq = spapr_irq_alloc(spapr, dev->irq, false, &local_err);
+ if (!dev->irq) {
+ dev->irq = spapr_irq_findone(spapr, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+
+ spapr_irq_claim(spapr, dev->irq, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 9dd46a72f6..6bfdf5a2fb 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -776,6 +776,10 @@ int spapr_irq_alloc(sPAPRMachineState *spapr, int
irq_hint, bool lsi,
Error **errp);
int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi,
bool align, Error **errp);
+int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align,
+ Error **errp);
+#define spapr_irq_findone(spapr, errp) spapr_irq_find(spapr, 1, false, errp)
+int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp);
void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num);
qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq);
--
2.17.1
- [Qemu-ppc] [PATCH 05/23] ppc/pnv: introduce Pnv8Chip and Pnv9Chip models, (continued)
- [Qemu-ppc] [PATCH 05/23] ppc/pnv: introduce Pnv8Chip and Pnv9Chip models, David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 09/23] spapr: Add cpu_apply hook to capabilities, David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 10/23] target/ppc: Add kvmppc_hpt_needs_host_contiguous_pages() helper, David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 21/23] target/ppc: Add ppc_hash64_filter_pagesizes(), David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 12/23] spapr: remove unused spapr_irq routines, David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 07/23] target/ppc: Allow cpu compatiblity checks based on type, not instance, David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 19/23] spapr: Maximum (HPT) pagesize property, David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 23/23] spapr: Don't rewrite mmu capabilities in KVM mode, David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 15/23] ppc4xx_i2c: Remove unimplemented sdata and intr registers, David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 13/23] fpu_helper.c: fix helper_fpscr_clrbit() function, David Gibson, 2018/06/22
- [Qemu-ppc] [PATCH 11/23] spapr: split the IRQ allocation sequence,
David Gibson <=
- [Qemu-ppc] [PATCH 18/23] pseries: Update SLOF firmware image to qemu-slof-20180621, David Gibson, 2018/06/22
- Re: [Qemu-ppc] [PATCH 01/23] ppc/pnv: introduce a new intc_create() operation to the chip model, Greg Kurz, 2018/06/22
- Re: [Qemu-ppc] [PATCH 01/23] ppc/pnv: introduce a new intc_create() operation to the chip model, Peter Maydell, 2018/06/26