qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Baumann <Andrew.Baumann@microsoft.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Igor Mitsyanko <i.mitsyanko@gmail.com>,
	Andrew Baumann <Andrew.Baumann@microsoft.com>,
	Sai Pavan Boddu <saipava@xilinx.com>,
	Peter Crosthwaite <crosthwaitepeter@gmail.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PATCH] sdhci: add quirk property for card insert interrupt status on Raspberry Pi
Date: Thu, 31 Dec 2015 13:40:43 -0800	[thread overview]
Message-ID: <1451598043-25924-1-git-send-email-Andrew.Baumann@microsoft.com> (raw)

This quirk is a workaround for the following hardware behaviour, on
which UEFI (specifically, the bootloader for Windows on Pi2) depends:

1. at boot with an SD card present, the interrupt status/enable
   registers are initially zero
2. upon enabling it in the interrupt enable register, the card insert
   bit in the interrupt status register is immediately set
3. after a subsequent controller reset, the card insert interrupt does
   not fire, even if enabled in the interrupt enable register

The implementation is relatively simple: if a card is present at power
on, remember that state as a "sticky" card insertion interrupt that
remains pending until enabled/cleared by the guest. We also need to
mask norintsts with norintstsen in sdhci_read, to avoid the interrupt
being visible before it is enabled.

Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
---
This is a little less savoury than the previous version. The real
ugliness here is that it can't be replaced by interposing on the card
insert interrupt between sd and sdhci (once they are refactored to
support it), because the interrupt needs to be "sticky" at the SDHCI
level.

I initially considered making all interrupts sticky in this way (i.e.,
unconditionally setting interrupts in the status register and masking
it with the enable register when read, but the SDHCI spec (section
1.8) is pretty clear that the interrupt status enable register acts as
a mask before the interrupt state is latched; i.e. if the interrupt
occurs but it is disabled, then it is forever lost.

One possible interpretation to explain what I'm seeing is that card
insertion is level-triggered, i.e. it is signalled as long as a card
remains inserted, but that would require a more extensive reworking of
the card insertion/removal interrupts logic, and would require yet
another quirk for item 3 above.

If anyone has suggestions for a cleaner fix, I'm all ears!

Thanks,
Andrew

 hw/sd/sdhci.c         | 11 ++++++++++-
 include/hw/sd/sdhci.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index dd83e89..6bce66a 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -892,7 +892,7 @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
         ret = s->clkcon | (s->timeoutcon << 16);
         break;
     case SDHC_NORINTSTS:
-        ret = s->norintsts | (s->errintsts << 16);
+        ret = (s->norintsts & s->norintstsen) | (s->errintsts << 16);
         break;
     case SDHC_NORINTSTSEN:
         ret = s->norintstsen | (s->errintstsen << 16);
@@ -1227,6 +1227,7 @@ static Property sdhci_pci_properties[] = {
     DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
             SDHC_CAPAB_REG_DEFAULT),
     DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
+    DEFINE_PROP_BOOL("bcm2835-quirk", SDHCIState, bcm2835_quirk, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -1306,6 +1307,14 @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
     memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
             SDHC_REGISTERS_MAP_SIZE);
     sysbus_init_mmio(sbd, &s->iomem);
+
+    /* Quirk for Raspberry Pi: set the card insert interrupt status.
+     * Needed to boot UEFI, which enables and then polls this bit at
+     * boot time before proceeding with card I/O.
+     */
+    if (s->bcm2835_quirk && (s->prnsts & SDHC_CARD_PRESENT)) {
+        s->norintsts |= SDHC_NIS_INSERT;
+    }
 }
 
 static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index e78d938..76fdd9b 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -77,6 +77,7 @@ typedef struct SDHCIState {
     uint32_t buf_maxsz;
     uint16_t data_count;   /* current element in FIFO buffer */
     uint8_t  stopped_state;/* Current SDHC state */
+    bool     bcm2835_quirk;/* Quirk for Raspberry Pi card insert status */
     /* Buffer Data Port Register - virtual access point to R and W buffers */
     /* Software Reset Register - always reads as 0 */
     /* Force Event Auto CMD12 Error Interrupt Reg - write only */
-- 
2.5.3

             reply	other threads:[~2015-12-31 21:41 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-31 21:40 Andrew Baumann [this message]
2016-01-01  5:38 ` [Qemu-devel] [PATCH] sdhci: add quirk property for card insert interrupt status on Raspberry Pi Peter Crosthwaite
2016-01-04 22:12   ` Andrew Baumann
2016-01-05  6:18     ` Peter Crosthwaite
2016-01-05 18:36       ` Andrew Baumann
2016-01-07  9:30         ` Peter Crosthwaite
2016-01-07 18:19           ` Andrew Baumann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1451598043-25924-1-git-send-email-Andrew.Baumann@microsoft.com \
    --to=andrew.baumann@microsoft.com \
    --cc=crosthwaitepeter@gmail.com \
    --cc=i.mitsyanko@gmail.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=saipava@xilinx.com \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).