qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-block] [Qemu-devel] [PATCH 7/9] AHCI: Rework IRQ constants


From: Philippe Mathieu-Daudé
Subject: Re: [Qemu-block] [Qemu-devel] [PATCH 7/9] AHCI: Rework IRQ constants
Date: Wed, 30 Aug 2017 00:24:03 -0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0

On 08/08/2017 03:33 PM, John Snow wrote:
Create a new enum so that we can name the IRQ bits, which will make
debugging
them a little nicer if we can print them out. Not handled in this
patch, but
this will make it possible to get a nice debug printf detailing
exactly which
status bits are set, as it can be multiple at any given time.

As a consequence of this patch, it is no longer possible to set
multiple IRQ
codes at once, but nothing was utilizing this ability anyway.

Signed-off-by: John Snow <address@hidden>
---
   hw/ide/ahci.c          | 49
++++++++++++++++++++++++++++++++++++++-----------
   hw/ide/ahci_internal.h | 44
+++++++++++++++++++++++++++++++++++---------
   hw/ide/trace-events    |  2 +-
   3 files changed, 74 insertions(+), 21 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index d5acceb..c5a9b69 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -56,6 +56,27 @@ static bool ahci_map_fis_address(AHCIDevice *ad);
   static void ahci_unmap_clb_address(AHCIDevice *ad);
   static void ahci_unmap_fis_address(AHCIDevice *ad);
   +static const char *AHCIPortIRQ_lookup[AHCI_PORT_IRQ__END] = {
+    [AHCI_PORT_IRQ_BIT_DHRS] = "DHRS",
+    [AHCI_PORT_IRQ_BIT_PSS]  = "PSS",
+    [AHCI_PORT_IRQ_BIT_DSS]  = "DSS",
+    [AHCI_PORT_IRQ_BIT_SDBS] = "SDBS",
+    [AHCI_PORT_IRQ_BIT_UFS]  = "UFS",
+    [AHCI_PORT_IRQ_BIT_DPS]  = "DPS",
+    [AHCI_PORT_IRQ_BIT_PCS]  = "PCS",
+    [AHCI_PORT_IRQ_BIT_DMPS] = "DMPS",
+    [8 ... 21]               = "RESERVED",
+    [AHCI_PORT_IRQ_BIT_PRCS] = "PRCS",
+    [AHCI_PORT_IRQ_BIT_IPMS] = "IPMS",
+    [AHCI_PORT_IRQ_BIT_OFS]  = "OFS",
+    [25]                     = "RESERVED",
+    [AHCI_PORT_IRQ_BIT_INFS] = "INFS",
+    [AHCI_PORT_IRQ_BIT_IFS]  = "IFS",
+    [AHCI_PORT_IRQ_BIT_HBDS] = "HBDS",
+    [AHCI_PORT_IRQ_BIT_HBFS] = "HBFS",
+    [AHCI_PORT_IRQ_BIT_TFES] = "TFES",
+    [AHCI_PORT_IRQ_BIT_CPDS] = "CPDS"
+};
     static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
   {
@@ -170,12 +191,18 @@ static void ahci_check_irq(AHCIState *s)
   }
     static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d,
-                             int irq_type)
+                             enum AHCIPortIRQ irqbit)
   {
-    DPRINTF(d->port_no, "trigger irq %#x -> %x\n",
-            irq_type, d->port_regs.irq_mask & irq_type);
+    g_assert(irqbit >= 0 && irqbit < 32);

Since you now use an enum this check is no more necessary.


You can actually still pass in a wrong value if you wanted to. This is
to prevent old-style IRQ masks from getting passed in by accident.

No accident :) This is now an enum, also:

hw/ide$ git grep ahci_trigger_irq
ahci.c:764:        ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_SDBS);
ahci.c:807:        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
ahci.c:810:    ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_PSS);
ahci.c:850:        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
ahci.c:853:    ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS);
ahci.c:1128:        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_OFS);
ahci.c:1276: ahci_trigger_irq(s, &s->dev[port], AHCI_PORT_IRQ_BIT_HBFS);

You only use enum values, not any cast.


However ...

+    uint32_t irq = 1U << irqbit;
+    uint32_t irqstat = d->port_regs.irq_stat | irq;
   -    d->port_regs.irq_stat |= irq_type;
+    trace_ahci_trigger_irq(s, d->port_no,
+                           AHCIPortIRQ_lookup[irqbit], irq,
+                           d->port_regs.irq_stat, irqstat,
+                           irqstat & d->port_regs.irq_mask);
+

Why not keep using masked irqs, and iterate over AHCI_PORT_IRQ__END
bits? Something like:

     if (TRACE_AHCI_IRQ_ENABLED) {
         int irqbit;
         for (irqbit = 0; irqbit < AHCI_PORT_IRQ__END; irqbit++) {
             if (irqmask & BIT(irqbit)) {
                 trace_ahci_trigger_irq(s, d->port_no, ...


Would rather not iterate like that for the IRQ path. Generally no place
in the codebase needs to raise more than one IRQ type at a time, so why
bother allowing it?

Indeed.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]