Skip to content

hisilicon: SD cards come up writable -- invert SDHCI write-protect where the kernel driver does - #210

Merged
openipc-ai merged 1 commit into
masterfrom
hisilicon-sdhci-wp-inverted
Oct 26, 2026
Merged

openipc-ai merged 1 commit into
masterfrom
hisilicon-sdhci-wp-inverted

Conversation

@openipc-ai

Copy link
Copy Markdown
Contributor

Fixes #209: on the HiSilicon / Goke machines whose kernel inverts the SDHCI write-protect pin, every -drive if=sd card came up read-only in the guest.

What changed

  • HisiSoCConfig.sdhci_wp_inverted. When it's set, the SDHCI loop sets wp-inverted on generic-sdhci.

  • It's set where the kernel driver carries SDHCI_QUIRK_INVERTED_WRITE_PROTECT:

    machines kernel (OpenIPC/linux branch) driver
    hi3516ev200, hi3516ev300, hi3518ev300, hi3516dv200 hisilicon-hi3516ev200 sdhci-hisi.c
    gk7205v200/v300, gk7201v200, gk7202v300, gk7605v100 (HISI_V4_COMMON_PERIPH) goke-gk7205v200 sdhci-goke.c
    gk7205v500/v510/v530, gk7202v330 (same macro) goke-gk7205v500 sdhci-xmedia-common.c
    gk7206v10, gk7206v12a (GK7206_XMORCA_PERIPH, via the macro) goke-gk7206v100 lotus/.../sdhci-lotus-common.c
  • It's left unset on hi3516cv608/cv610/cv613 and hi3519dv500/hi3516dv500. Their nebula driver (drivers/vendor/mmc) uses the spec polarity, which QEMU already gives it.

  • New qemu/tests/test-hisi-sdhci-wp.sh, run in the CI build job and listed in CLAUDE.md.

Evidence

bash qemu/tests/test-hisi-sdhci-wp.sh: master gives 2 passed, 8 failed (every inverted machine reads PRNSTS 0x01ff0000, WP bit 1). This branch gives 10 passed, 0 failed (inverted machines 0x01f70000; nebula controls unchanged at 0x01ff0000).

Booted from synthetic NOR (the test-flash-rw.sh layout) with the OpenIPC lite releases in qemu-boot/ and a FAT32 card:

machine master this branch
hi3516ev300 mmcblk0: mmc0:3244 QEMU! 64.0 MiB (ro) → vfat ro mmcblk0: mmc0:7438 QEMU! 64.0 MiB → vfat rw
gk7205v200 (ro), same as ev300 mmcblk0: mmc0:6b5f QEMU! 64.0 MiB → vfat rw

Not covered

  • gk7205v500: the release kernel boots to login but probes no SD host at all, with or without this change (CONFIG_MMC_SDHCI_XMEDIA=y and nothing binds). For that machine the polarity is covered only by the register test. The missing probe is a separate gap.
  • Read-only cards: not testable. QEMU 10.2 refuses a read-only drive as an SD card.
  • Nebula and gk7206 boots: no boot-level run on those machines.

…ere the kernel driver does

Every card attached with -drive if=sd to a hi3516ev200/ev300, hi3518ev300,
hi3516dv200 or Goke V4/V500/xmorca machine was registered by the guest as
write-protected ("mmcblk0: ... QEMU! 64.0 MiB (ro)"), so every mount came
out read-only.  The guest tests that use the card only read from it, so
none of them noticed.

QEMU's generic-sdhci sets PRNSTS bit 19 for a writable card, as the SDHCI
spec has it.  The vendor drivers these kernels bind read the pin the other
way round, each through SDHCI_QUIRK_INVERTED_WRITE_PROTECT in its
sdhci_pltfm_data:

  hisilicon-hi3516ev200   drivers/mmc/host/sdhci-hisi.c
  goke-gk7205v200         drivers/mmc/host/sdhci-goke.c
  goke-gk7205v500         drivers/mmc/host/sdhci-xmedia-common.c
  goke-gk7206v100         lotus/drivers/mmc/host/sdhci-lotus-common.c

The nebula driver behind hi3516cv608/cv610/cv613 and hi3519dv500/
hi3516dv500 (drivers/vendor/mmc in the hisilicon-hi3516cv6xx and
-hi3519dv500 kernels) sets no such quirk and has no get_ro, so it takes
the spec polarity, which QEMU already gives it.  That rules out flipping
the property for every machine, so HisiSoCConfig gains sdhci_wp_inverted.
It is set in the four EV200-family entries and in HISI_V4_COMMON_PERIPH,
which every Goke machine on this path includes (GK7206_XMORCA_PERIPH
through it).  goke.c already does the same for the GK710x SDIO.

qemu/tests/test-hisi-sdhci-wp.sh reads PRNSTS with a writable card in
slot 0 on one machine per driver: bit 19 clear on the eight inverted
machines, set on cv610 and dv500.  Against master, the eight fail and the
two nebula controls pass.  It runs in the CI build job.  A read-only card
can't be tested: QEMU refuses a read-only drive as an SD card.

Booted from NOR with the OpenIPC lite releases in qemu-boot/, a FAT32
card now registers without "(ro)" and automount mounts it rw on
hi3516ev300 and gk7205v200.  The gk7205v500 release boots to login but
probes no SD host at all, with or without this change, so its polarity
is covered by the register test only.

Fixes #209.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Match HiSilicon and Goke SDHCI write-protect polarity to guest drivers

🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Invert SDHCI write-protect polarity on machines whose guest drivers require it, so writable cards
 mount read-write.
• Preserve spec polarity on nebula-driven machines.
• Add register-level coverage for both polarities and run it in CI.
Diagram

graph TD
  Config["SoC config"] --> Quirk{"Driver inverts WP?"} -->|yes| Inverted["Inverted polarity"] --> SDHCI["Generic SDHCI"] --> Driver["Guest SD driver"] --> Mount["Writable SD card"]
  Quirk -->|no| Spec["Spec polarity"] --> SDHCI
Loading
High-Level Assessment

Keep the per-SoC flag and set the existing generic-sdhci property during common initialization. Globally reversing polarity would regress nebula-driven machines; a separate controller model is unnecessary for a property the existing device already supports.

Files changed (5) +107 / -0

Bug fix (2) +17 / -0
hisilicon.cConfigure SDHCI write-protect polarity per SoC +13/-0

Configure SDHCI write-protect polarity per SoC

• Enables inverted polarity for four EV200-family configurations and the shared Goke V4 configurations. Passes each configuration's polarity to generic-sdhci during controller initialization.

qemu/hw/arm/hisilicon.c

hisilicon.hAdd an SDHCI polarity setting to SoC configuration +4/-0

Add an SDHCI polarity setting to SoC configuration

• Adds sdhci_wp_inverted to HisiSoCConfig, allowing affected machines to opt in while others retain the default polarity.

qemu/include/hw/arm/hisilicon.h

Tests (1) +83 / -0
test-hisi-sdhci-wp.shCheck writable-card WP status across machine families +83/-0

Check writable-card WP status across machine families

• Attaches a writable SD image and checks PRNSTS bit 19 on eight inverted-polarity machines and two nebula controls. Reports unreadable registers and polarity mismatches as failures.

qemu/tests/test-hisi-sdhci-wp.sh

Documentation (1) +1 / -0
CLAUDE.mdList the SDHCI polarity test +1/-0

List the SDHCI polarity test

• Adds the test command to the documented device-register test list.

CLAUDE.md

Other (1) +6 / -0
ci.ymlRun SDHCI polarity regression test in CI +6/-0

Run SDHCI polarity regression test in CI

• Adds the HiSilicon/Goke write-protect test to the build job so polarity regressions are caught automatically.

.github/workflows/ci.yml

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can type 'qodo, fix this' on a finding and the fix lands right on your PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@openipc-ai
openipc-ai merged commit 713e7f9 into master Oct 26, 2026
27 checks passed
@openipc-ai
openipc-ai deleted the hisilicon-sdhci-wp-inverted branch October 26, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hisilicon: SD cards on generic-sdhci machines come up write-protected — vendor driver inverts the WP bit, wp-inverted is never set

1 participant