Repository navigation
spi: apple-qspi: J616s NVRAM writes and boot NOR DT (asahi-bless on the M4 Pro) - #662
Closed
RyanTheTide wants to merge 6 commits into
Closed
RyanTheTide wants to merge 6 commits into
RyanTheTide wants to merge 6 commits into
Conversation
asahi-bless cannot select a one-time boot volume on the MacBook Neo (J700). The T8140 path admitted programs and erases inside the nvram partition with no runtime opt-in and no readback, while the J613 and J713 go through the read-only, opt-in, verified policy. Writes still never reached the flash, because the partition was read-only in MTD. Put the J700 on the same policy. The controller starts read-only and root opts in at runtime through the read_only parameter. A write needs the J700 board and the controller at 0x385110000. Programs are single-wire, three-byte, within one 256-byte page; erases are aligned 4 KiB sectors; both must lie inside the nvram partition. Every mutation checks the JEDEC ID and status first, is verified by readback, and a fault latches the driver read-only. The J613/J713 partition is pinned at 0x700000. The J700's comes from its device tree (0x24000, size 0x1d0000), so the range check now takes the partition bounds, and a DT window must fit in three-byte addressing. The J700 flash is a W25Q16JV (JEDEC ef6515). iBoot leaves BP0 set, which protects the top 64 KiB, so the J700 tolerates the block-protect bits as found: the driver never changes them, the flash ignores writes in that range, and readback then latches read-only. CMP, suspend, WPS, BUSY and WEL are still refused. T8140 data reads keep their multi-line pass-through. KUnit and the host harness now cover the shared policy at the J700 bounds, the J700 board gate and the block-protect tolerance. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The J700 nvram partition starts at 0x24000 on its boot NOR. SPI-NOR picks the largest uniform erase size unless MTD_SPI_NOR_USE_4K_SECTORS is set, so the flash reports 64 KiB erase blocks and MTD forces the partition read-only because it does not start on an erase boundary. asahi-bless then cannot set a boot volume. There is no device tree or per-flash way to choose the erase size; this option is the only switch, and it is the upstream default. The Fedora base config turns it off. Set it again. The Apple NVRAM partitions are managed in 4 KiB units, and the QSPI NVRAM policy on the J613, J713 and J700 only admits 4 KiB erases anyway. Other SPI NOR users only see smaller erase blocks. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each board that may write its NVRAM was qualified by its own compatible check in apple_qspi_nvram_write_board(), and probe then picked the partition bounds, JEDEC ID and block-protect allowance from whether the controller was T8140. The J613/J713 partition was a pair of constants, checked by a second device tree walk, while the J700 one came from the device tree unchecked. Put the qualified boards in one table: controller compatible, machine, controller aperture, the nvram partition the device tree must describe, the flash JEDEC ID and the block-protect bits its firmware leaves set. Every controller now reads its nvram partition from the device tree with the same walk, and a board is a write candidate only when that partition is exactly the one in its table entry. The T8140 multi-line read pass-through comes from the compatible match data. The J613 and J713 keep the 0x700000 partition and the W25Q64 ID, and the J700 keeps 0x24000, the W25Q16 ID and its BP tolerance, now with its partition pinned as well. The KUnit 0x700000 case covers the partition edges against its neighbours, and the host harness reads the table and gains controller, aperture and partition controls. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
The M4 Pro (T6041) boot NOR sits behind the same QSPIMC controller as the M3, M4 and A18 Pro parts, at 0x429118000. The J616s ADT places its nvram partition (anvram, "nvram,nor") at 0x700000 with a size of 1 MiB, the J613 and J713 layout, next to iboot at 0 and syscfg at 0x680000. Without a T6041 match the driver does not bind, so asahi-bless cannot select a boot volume from Linux. Match apple,t6041-qspi with single-line transfers, as on T8122 and T8132. Qualify the J616s for the verified NVRAM policy at its controller aperture and that partition, with the W25Q64 ID the other 0x700000 boards use and no block-protect bits tolerated. The flash ID is checked before every program or erase, so a different part is refused before any write enable reaches it. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Describe the J616s boot NOR on the QSPIMC controller with the nvram partition from its ADT (/arm-io/qspi/spinor/anvram, 0x700000, 1 MiB), so asahi-nvram and asahi-bless can find it. Use single-line transfers at 10 MHz, as on the J713. Add the nvram and spi0 aliases the J700 also carries. The SoC node stays disabled for boards that do not describe their flash. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
macOS reports the J616s boot NOR JEDEC ID as c22b27, a Macronix part, not the Winbond W25Q64 the J613 and J713 carry. Pin that ID in the J616s table entry. The write policy and the flash_status attribute read status registers with Winbond opcodes: 05h, 35h and 15h. On Macronix parts 35h is EQIO, which switches the flash to QPI mode, and the status register keeps four block-protect bits, BP[3:0] at bits 5:2, where Winbond has three and TB. For a Macronix part, read only the status (05h) and configuration (15h) registers, refuse 35h from SPI-NOR as well, and check WIP, WEL and all four BP bits before a write. flash_status reads the JEDEC ID first and sends 35h only to Winbond parts. The J616s still admits only 3-byte page programs and 4 KiB sector erases (20h) inside its nvram partition, with readback verification. SPI-NOR has no table entry for c22b27; it binds through the generic Macronix entry and takes geometry and erase types from SFDP. Assisted-by: LLM Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
This was referenced Oct 31, 2026
Contributor
Author
|
Superseded by #674, which carries the same change with the house trailers and is merged into aurora-wip after the fleet12 hardware run. 🤖 Generated with Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This lets
asahi-bless --nextpick macOS for one boot on the M4 Pro MacBook Pro (J616s), the way it works on the Neo.It stacks on #626, which puts every QSPIMC board on the verified NVRAM write policy. Its two commits show here until it merges. The four new commits are the last four.
Changes
apple,t6041-qspibinds with single-line transfers like T8122/T8132. The J616s qualifies at 0x429118000 with the 0x700000 / 1 MiB partition, with no BP bits tolerated.&qspigetsflash@0andnvram: partition@700000from the J616s ADT (anvram, "nvram,nor"), single-line at 10 MHz like the J713, plus thenvramandspi0aliases the J700 has.flash_statusreads the JEDEC ID first and sends 35h only to Winbond parts. SPI-NOR has no entry for c22b27 and binds it through the generic Macronix entry from SFDP, which never issues 35h on a single-line setup (the SFDP quad-enable method for Macronix is SR1 bit 6).The partition and controller facts are from the macOS 27.0 ADT on the J616s:
qspi@29118000with windows at 0x429118000 and 0x429118800, IRQ 1573, andspinor@0with firmware@0, syscfg@0x680000 and anvram@0x700000 (size 0x100000).Not known yet
flash_statusshould showjedec=c22b27 sr=.. cr=..on first boot. The ID is checked before every program or erase, so a mismatch gets -ENODEV before any write enable.spi0alias moves the Touch ID controller (spi2) from dynamic bus 0 to bus 1. Nothing in the tree names that bus, but Touch ID should be checked once on hardware.Tested
On the buildbox, on aurora-wip 8348f82 with PR 626 cherry-picked (the stack merges into aurora-wip with no conflicts and the same tree):
spi-apple-qspi.oandspi-apple-qspi-policy-test.obuild with W=1 and no warnings (defconfig + asahi.config, LLVM).make CHECK_DTBS=yfor t6040-j616s, t6040-j616s-tether, t8140-j700, t8132-j713 and t8122-j613-25g83, no warnings. The J616s dtb has the flash, the partition and both aliases.dt_binding_check DT_SCHEMA_FILES=spi/apple,qspi.yamlpasses.apple-qspi-nvram-policyunder UML, 9/9 pass, including the 0x700000 partition edges and the Macronix status check.tools/asahi/qspi-nvram-tests.pyall PASS, now covering 140 board/controller/aperture combinations, a Macronix write sequence that asserts 35h never reaches the wire, BP0 to BP3 refusal, and changed-guard controls for the controller, board, aperture, J616s aperture and partition, Macronix BP3, and both EQIO guards.Not tested on hardware. Please don't merge until a J616s run reads the NOR, shows the JEDEC ID and completes a
--nextset, macOS boot and return.Assisted-by: LLM
🤖 Generated with Claude Code