You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
hisilicon: SD cards on generic-sdhci machines come up write-protected — vendor driver inverts the WP bit, wp-inverted is never set #209
On the HiSilicon machines that wire their SD slot as QEMU's generic-sdhci (hw/arm/hisilicon.c, the num_sdhci / sdhci_bases loop), every card attached with -drive if=sd is presented to the guest as write-protected. The OpenIPC kernel then registers it read-only, and every mount comes out ro:
This applies to a writable raw image, the same way test-flash-rw.sh / test-firstboot.sh attach theirs. Those tests only read the card, so neither has noticed.
Cause
The vendor SDHCI driver reads the write-protect pin the opposite way from the SDHCI spec. drivers/mmc/host/sdhci-hisi.c in OpenIPC/linux's hisilicon-hi3516ev200 tarball (ev200 / ev300 / 18ev300 / dv200 all include it):
QEMU's sdhci_set_readonly() sets PRNSTS bit 19 (SDHC_WRITE_PROTECT) for a writable card. Linux's sdhci_check_ro() then inverts that because of the quirk, so the card comes out read-only. hisilicon.c never sets wp-inverted on its TYPE_SYSBUS_SDHCI instances. hw/arm/goke.c already handles the same thing for the GK710x SDIO (qdev_prop_set_bit(dev, "wp-inverted", true), citing gk_sd_get_ro).
Booted from a synthetic NOR as test-flash-rw.sh does, with a 64 MiB FAT32 card:
run
kernel
mount
as is
mmcblk0: mmc0:3244 QEMU! 64.0 MiB (ro)
vfat ro,...
-global generic-sdhci.wp-inverted=on
mmcblk0: mmc0:80f7 QEMU! 64.0 MiB
vfat rw,...
Suggested fix
In the SDHCI loop in hisilicon.c, qdev_prop_set_bit(sdhci, "wp-inverted", true) before realize, with a comment citing SDHCI_QUIRK_INVERTED_WRITE_PROTECT. A per-SoC flag would be needed if any of the other kernels behind this loop turn out not to carry the quirk.
Not verified: the kernels of the other machines that go through the same loop: hi3516cv608 / cv610 / cv613, hi3519dv500 / hi3516dv500 and gk7202v330. I have only checked the ev200-family sdhci-hisi.c. Their drivers should be checked for the same quirk before flipping it everywhere.
Why it matters
Any guest test that writes to the card, or depends on how a rw mount behaves, is testing something real cameras never do. I ran into it while reproducing OpenIPC/firmware#170 (kernel log noise from SD automount). A read-only device makes every rw mount attempt fail in the VFS before any filesystem's fill_super runs, so the noise that issue is about cannot appear.
Cause: as described above, with one correction to the suggested fix. Not every machine behind the SDHCI loop inverts the pin. The kernels that do, each through SDHCI_QUIRK_INVERTED_WRITE_PROTECT:
hisilicon-hi3516ev200: sdhci-hisi.c
goke-gk7205v200: sdhci-goke.c
goke-gk7205v500: sdhci-xmedia-common.c
goke-gk7206v100: sdhci-lotus-common.c
The nebula driver behind hi3516cv608/cv610/cv613 and hi3519dv500/hi3516dv500 uses the spec polarity. Flipping wp-inverted everywhere would have broken those machines.
Fix: a per-SoC HisiSoCConfig.sdhci_wp_inverted. It's set on the four EV200-family entries and in HISI_V4_COMMON_PERIPH, which covers every Goke machine on this path.
Evidence:
qemu/tests/test-hisi-sdhci-wp.sh (now in the CI build job): 8 failed / 2 passed on master, and 10/10 passed on the branch and in CI.
With the OpenIPC lite release kernel and a FAT32 card, hi3516ev300 and gk7205v200 now register mmcblk0: ... QEMU! 64.0 MiB without (ro), and automount mounts it vfat rw.
Gaps:
The gk7205v500 release kernel probes no SD host at all, before and after this change, so on that machine only the register test covers it.
The nebula and gk7206 machines weren't boot-tested.
A read-only card can't be tested: QEMU refuses a read-only SD drive.
Activity
openipc-ai commentedon Oct 26, 2026
Fixed by #210 (
713e7f9).Cause: as described above, with one correction to the suggested fix. Not every machine behind the SDHCI loop inverts the pin. The kernels that do, each through
SDHCI_QUIRK_INVERTED_WRITE_PROTECT:hisilicon-hi3516ev200:sdhci-hisi.cgoke-gk7205v200:sdhci-goke.cgoke-gk7205v500:sdhci-xmedia-common.cgoke-gk7206v100:sdhci-lotus-common.cThe nebula driver behind hi3516cv608/cv610/cv613 and hi3519dv500/hi3516dv500 uses the spec polarity. Flipping
wp-invertedeverywhere would have broken those machines.Fix: a per-SoC
HisiSoCConfig.sdhci_wp_inverted. It's set on the four EV200-family entries and inHISI_V4_COMMON_PERIPH, which covers every Goke machine on this path.Evidence:
qemu/tests/test-hisi-sdhci-wp.sh(now in the CI build job): 8 failed / 2 passed on master, and 10/10 passed on the branch and in CI.mmcblk0: ... QEMU! 64.0 MiBwithout(ro), and automount mounts itvfat rw.Gaps: