> From: Peter Crosthwaite [mailto:crosthwaitepe...@gmail.com] > Sent: Saturday, 5 December 2015 21:26 > Is this IP just SDHCI? We already model SDHCI in QEMU, see > hw/sd/sdhci.c. If there are RPi specific features to the SDHCI > implementation they should be added as optional extensions (probabably > via subclassing) to the existing SDHCI model.
So yes, it turns out this is fairly similar to SDHCI (-> lots of wasted work by Gregory and me, sigh), and indeed Linux boots with the existing sdhci emulation. However, there are some quirks, and UEFI/Windows depend on them. Namely: * The host control registers (offset 0x28 and above) seem to differ significantly. Maybe this is due to the SDHC version -- according to the BCM2835 peripherals spec, the controller implements "Version 3.0 Draft 1.0" of the SDHC spec, but of course I can't find that spec online anywhere. Luckily nothing seems to depend on this, besides a few spurious warnings about invalid writes. * Power is assumed to be always on -- the sdhci model requires the guest to turn it on by a write at offset 0x29 before issuing any commands, but on pi this bit is marked reserved, and commands are issued immediately after reset. * The card inserted interrupt is rather broken on pi: it is set at the start of day, but a reset command clears it and it stays clear thereafter (and never generates interrupts). There's an inconsistency with response handling, too, although I'm not sure if it's a quirk of the Pi or a general bug in sdhci. Pi UEFI sends a CMD23 without setting any of the response bits, but this command does in fact generate a 4-byte R1 response. The question is whether this should be treated as an error, or whether it simply means that the host wants to ignore the response. In sdhci, the following code path (around line 246) raises a "command index" error in the case that a non-zero response is returned but no response bits were set in the command register: } else if (rlen != 0 && (s->errintstsen & SDHC_EISEN_CMDIDX)) { s->errintsts |= SDHC_EIS_CMDIDX; s->norintsts |= SDHC_NIS_ERR; } I do not observe this behaviour on the real Pi2 (and it breaks UEFI). The hardware semantics appear to be "if the command generates a response, but you didn't want to see it, we'll successfully complete the command and ignore the response", whereas the sdhci implementation raises an error for this as well as signalling completion. I have read the "SD Specifications Part A2 SD Host Controller Simplified Specification Version 2.00", but did not find anything describing this case, so it could be that this is open to interpretation. (It could also be specified in SDHC v3.) The specific error also seems odd -- my understanding is that a "command index" error means that the index in the response didn't match the index of the issued command, but that's hardly what is happening here. Assuming this latter bug can be fixed generically, how do you propose handling the Pi quirks? I could add a bool property for "bcm2835-quirks" or similar and just special-case the relevant code (my preferred approach). I'm also open to subclassing, but no idea how that would work in practice, so would need some pointers. Thanks, Andrew