Project

General

Profile

Actions

Bug #671

open
GT

jedec: Erasing offset zero targets the unlock address (Pm49FL004)

Bug #671: jedec: Erasing offset zero targets the unlock address (Pm49FL004)

Added by Gianluigi Tiesi 5 days ago. Updated 5 days ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
Programmer
Target version:
Start date:
11/06/2026
Due date:
% Done:

0%

Estimated time:
Affected versions:
Needs backport to:
Affected hardware:
Linutop 2, FIC ION603
Affected OS:
Linux

Description

flashrom's JEDEC erase helper replaces a valid target offset of zero with
the unlock address. On a Pm49FL004, this makes a request to erase the first
4 KiB sector target the sector at 0x5000 instead. Besides failing to erase
the requested sector, this can erase data outside the requested region.

Affected versions

  • flashrom 1.8.0: reproduced with a recording-bus test of the real jedec.c.
  • Upstream main at 30dc47c886517fa46ce205500c2d2bf30623f96b:
    the same test reproduces the problem (checked on 2026-11-06).

Cause

issuecmd() currently contains:

if (!operand)
    operand = (shifted ? JEDEC_UNLOCK_ADDR2 : JEDEC_UNLOCK_ADDR1) & mask;

erase_sector_jedec() passes the requested sector offset as operand. When
that offset is zero, the final 0x30 command is sent to offset 0x5555 on
the Pm49FL004. That address selects the 4 KiB sector at 0x5000, whereas
the requested erase range is 0x0000-0x0fff.

Zero is also a valid operand for erase_block_jedec(). The physical effect
of substituting an unlock address depends on the chip's erase geometry.

Reproduction without hardware

The attached test_jedec_address.c links the real jedec.c with recording
chip_writeb() and mocked read/delay/log functions. It checks all six writes
in each erase sequence; it does not access hardware.

From the flashrom source directory, with the test file in that directory:

cc -std=c11 -ffunction-sections -fdata-sections -Iinclude -I. \
    test_jedec_address.c jedec.c -Wl,--gc-sections -o test-jedec-address
./test-jedec-address

The unmodified source reports, among other failures:

FAIL PMC sector 0: cycle 6 address=0x5555 expected=0x0 data=0x30

Expected: the final 0x30 command is written at offset 0x0000. Erase setup
and whole-chip erase must still use the appropriate unlock address.

Proposed fix

Use the default unlock address only for JEDEC_CMD_ERASE (0x80, erase
setup) and JEDEC_CMD_ERASE_CHIP (0x10). Preserve the supplied operand for
sector and block erase, including zero. The attached patch passes all
nine standalone cases on both 1.8.0 and the main revision above: zero and
nonzero sector/block targets, chip erase, masked and shifted addresses.

Hardware validation of patched 1.8.0

  • Linutop 2, FIC ION603 PCB 2.X; AMD Geode LX / CS5536.
  • PMC Pm49FL004, 512 KiB, LPC/FWH.
  • OpenWrt SNAPSHOT r38095-df5dc61652, x86/geode, Linux 6.18.60.
  • Initial sector test: -p internal -c Pm49FL004.

A layout limited writes to 0x0000-0x0fff. One byte at 0x0800 was changed
from 0xff to 0xfe, then the original image was restored. Restoring that
byte requires an erase. The restore log shows E(0:fff); programming and
restoration both returned success and passed verification. A separate
full-chip read matched the original 524288-byte backup byte for byte.

The board owner subsequently tested the full 512 KiB BIOS image with the
patched OpenWrt flashrom-pci 1.8.0-r2 package and confirmed the BIOS works
on the Linutop. The supplied command and output are attached separately
as full-bios-write.txt:

flashrom-pci -VV -w linutop-stock-ipxe-a040f957-i386.rom

This uses the default internal programmer without additional parameters
or a restricted layout. The log identifies the Pm49FL004 and includes:

Added layout entry 00000000 - 0007ffff named complete flash
Erase/write done from 0 to 7ffff
Runtime from programmer init to shutdown: 0min 1sec

The captured run contains no E(...)/W(...) operation markers or VERIFIED
message. In flashrom 1.8.0 this is consistent with all writes being skipped
because the existing contents already match the image. It documents a
full-image write request completing without a reported error, rather than
independent evidence of a fresh erase/program cycle over the whole chip.
The explicit sector-zero erase and readback evidence is in the earlier
controlled test; boot-block rewriting is not established by this log.

No iomem=relaxed or laptop override was needed. The standalone tests are
separate from the upstream unit-test suite, which has not been run for
this patch.

Attachments

  • 100-jedec-preserve-zero-erase-address.patch
  • test_jedec_address.c
  • test-jedec-main-original.txt and test-jedec-main-fixed.txt
  • program.txt and restore.txt (hardware logs)
  • full-bios-write.txt (full-image command and output supplied by the owner)

AI assistance disclosure

OpenAI Codex assisted with diagnosis, patch and report drafting, and the
initial test execution. The subsequent full-image test and its output
were supplied by the board owner. The hardware results were collected on
the actual board; the command-address results come from the standalone
recording-bus test.


Files

100-jedec-preserve-zero-erase-address.patch (586 Bytes) 100-jedec-preserve-zero-erase-address.patch Gianluigi Tiesi, 11/06/2026 08:00 PM
test_jedec_address.c (2.93 KB) test_jedec_address.c Gianluigi Tiesi, 11/06/2026 08:00 PM
test-jedec-main-original.txt (374 Bytes) test-jedec-main-original.txt Gianluigi Tiesi, 11/06/2026 08:00 PM
test-jedec-main-fixed.txt (187 Bytes) test-jedec-main-fixed.txt Gianluigi Tiesi, 11/06/2026 08:00 PM
program.txt (2.82 KB) program.txt Gianluigi Tiesi, 11/06/2026 08:01 PM
restore.txt (3.07 KB) restore.txt Gianluigi Tiesi, 11/06/2026 08:01 PM
full-bios-write.txt (24.5 KB) full-bios-write.txt Gianluigi Tiesi, 11/06/2026 08:01 PM
Actions

Also available in: PDF Atom