summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--Makefile6
-rw-r--r--doc/classic_cli_manpage.rst2
-rw-r--r--doc/index.rst1
-rw-r--r--doc/supported_hw/index.rst8
-rw-r--r--doc/supported_hw/supported_prog/index.rst16
-rw-r--r--doc/supported_hw/supported_prog/serprog/166px-Serprogduino_v2.jpegbin0 -> 10900 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/250px-Arduino_5V_lpc_spi_shield.jpgbin0 -> 11789 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/250px-Arduino_lpcspi_shield_render.pngbin0 -> 89425 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/300px-AtmegaXXu2-flasher.jpgbin0 -> 17753 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/300px-Avr_rs232_programmer.jpgbin0 -> 10452 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/300px-HydraFW_Default_PinAssignment.pngbin0 -> 60506 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/300px-Serprog_0001.jpegbin0 -> 10382 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/300px-Teensy31_lpcspi_flasher.jpgbin0 -> 21723 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/P1v1_arduino328.pngbin0 -> 32174 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/P1v2_arduino1280.pngbin0 -> 57028 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/P2v1_resdivider.pngbin0 -> 27895 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/P2v2_oc_cs.pngbin0 -> 19645 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/P2v3_buffer4050.pngbin0 -> 30877 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/P3v1_dil8_so8_spi.pngbin0 -> 32207 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/P3v2_so16_spi.pngbin0 -> 22444 bytes
-rw-r--r--doc/supported_hw/supported_prog/serprog/arduino_flasher.rst227
-rw-r--r--doc/supported_hw/supported_prog/serprog/arduino_flasher_3.3v.rst237
-rw-r--r--doc/supported_hw/supported_prog/serprog/index.rst11
-rw-r--r--doc/supported_hw/supported_prog/serprog/overview.rst83
-rw-r--r--doc/supported_hw/supported_prog/serprog/serprog-protocol.rst (renamed from Documentation/serprog-protocol.txt)103
-rw-r--r--doc/supported_hw/supported_prog/serprog/teensy_3_1.rst81
-rw-r--r--doc/user_docs/chromebooks.rst8
-rw-r--r--doc/user_docs/index.rst1
-rw-r--r--erasure_layout.c54
-rw-r--r--flashchips.c138
-rw-r--r--flashrom.c29
-rw-r--r--include/flashchips.h6
-rw-r--r--meson.build3
-rw-r--r--meson_cross/i586_djgpp_dos.txt6
-rw-r--r--meson_options.txt3
-rw-r--r--tests/udelay.c18
-rw-r--r--udelay.c9
-rw-r--r--udelay_dos.c11
-rw-r--r--util/flashrom_tester/Cargo.toml3
-rw-r--r--util/flashrom_tester/src/utils.rs5
-rw-r--r--util/flashrom_udev.rules3
42 files changed, 992 insertions, 81 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 97b60382d..f4e0c9a52 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -78,6 +78,7 @@ Maintainers List (try to look for most precise areas first)
BUILD SYSTEM
M: Thomas Heijligen <src@posteo.de>
+M: Peter Marheine <pmarheine@chromium.org>
S: Maintained
F: Makefile*
F: meson*
diff --git a/Makefile b/Makefile
index 9b94e22b2..97f56b83c 100644
--- a/Makefile
+++ b/Makefile
@@ -542,6 +542,11 @@ CONFIG_NI845X_SPI ?= no
# Disable wiki printing by default. It is only useful if you have wiki access.
CONFIG_PRINT_WIKI ?= no
+# Minimum time in microseconds to suspend execution for (rather than polling)
+# when a delay is required. Larger values may perform better on machines with
+# low timer resolution, at the cost of increased power.
+CONFIG_DELAY_MINIMUM_SLEEP_US ?= 100000
+
# Disable all features if CONFIG_NOTHING=yes is given unless CONFIG_EVERYTHING was also set
ifeq ($(CONFIG_NOTHING), yes)
ifeq ($(CONFIG_EVERYTHING), yes)
@@ -587,6 +592,7 @@ FEATURE_FLAGS += -D'CONFIG_DEFAULT_PROGRAMMER_NAME=NULL'
endif
FEATURE_FLAGS += -D'CONFIG_DEFAULT_PROGRAMMER_ARGS="$(CONFIG_DEFAULT_PROGRAMMER_ARGS)"'
+FEATURE_FLAGS += -D'CONFIG_DELAY_MINIMUM_SLEEP_US=$(CONFIG_DELAY_MINIMUM_SLEEP_US)'
################################################################################
diff --git a/doc/classic_cli_manpage.rst b/doc/classic_cli_manpage.rst
index f40d19ee5..beafd82b4 100644
--- a/doc/classic_cli_manpage.rst
+++ b/doc/classic_cli_manpage.rst
@@ -749,7 +749,7 @@ chips at once and selecting which one to flash by software means (rather than re
The particular programmer implementation needs to support this feature, for it to work. If the requested chip
select isn't available, flashrom will fail safely.
-More information about serprog is available in **serprog-protocol.txt** in the source distribution.
+More information about serprog is available in this document: :doc:`/supported_hw/supported_prog/serprog/serprog-protocol`.
buspirate_spi programmer
diff --git a/doc/index.rst b/doc/index.rst
index 60c42b0bf..f32f18298 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -12,6 +12,7 @@
dev_guide/index
user_docs/index
contrib_howtos/index
+ supported_hw/index
classic_cli_manpage
contact
release_notes/index
diff --git a/doc/supported_hw/index.rst b/doc/supported_hw/index.rst
new file mode 100644
index 000000000..058e7f2ec
--- /dev/null
+++ b/doc/supported_hw/index.rst
@@ -0,0 +1,8 @@
+==================
+Supported hardware
+==================
+
+.. toctree::
+ :maxdepth: 1
+
+ supported_prog/index
diff --git a/doc/supported_hw/supported_prog/index.rst b/doc/supported_hw/supported_prog/index.rst
new file mode 100644
index 000000000..d8131a634
--- /dev/null
+++ b/doc/supported_hw/supported_prog/index.rst
@@ -0,0 +1,16 @@
+Supported programmers
+=====================
+
+flashrom supports many different programmers, for the full list you can look into `programmer_table.c <https://github.com/flashrom/flashrom/blob/main/programmer_table.c>`_
+in the source tree. Some of the programmers have their own documentation pages, see below.
+
+If you can run flashrom locally, the command ``flashrom -L`` prints all devices supported per programmer
+(see :doc:`/classic_cli_manpage` for more details on command line options). The output of this command is long, so you might
+want to save it to file or grep.
+
+Patches to add/update documentation, or migrate docs from `old wiki website <https://wiki.flashrom.org/Supported_programmers>`_ are very much appreciated.
+
+.. toctree::
+ :maxdepth: 1
+
+ serprog/index
diff --git a/doc/supported_hw/supported_prog/serprog/166px-Serprogduino_v2.jpeg b/doc/supported_hw/supported_prog/serprog/166px-Serprogduino_v2.jpeg
new file mode 100644
index 000000000..ffe85588f
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/166px-Serprogduino_v2.jpeg
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/250px-Arduino_5V_lpc_spi_shield.jpg b/doc/supported_hw/supported_prog/serprog/250px-Arduino_5V_lpc_spi_shield.jpg
new file mode 100644
index 000000000..1886e260b
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/250px-Arduino_5V_lpc_spi_shield.jpg
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/250px-Arduino_lpcspi_shield_render.png b/doc/supported_hw/supported_prog/serprog/250px-Arduino_lpcspi_shield_render.png
new file mode 100644
index 000000000..02b139e5e
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/250px-Arduino_lpcspi_shield_render.png
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/300px-AtmegaXXu2-flasher.jpg b/doc/supported_hw/supported_prog/serprog/300px-AtmegaXXu2-flasher.jpg
new file mode 100644
index 000000000..1a78faa90
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/300px-AtmegaXXu2-flasher.jpg
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/300px-Avr_rs232_programmer.jpg b/doc/supported_hw/supported_prog/serprog/300px-Avr_rs232_programmer.jpg
new file mode 100644
index 000000000..618037b59
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/300px-Avr_rs232_programmer.jpg
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/300px-HydraFW_Default_PinAssignment.png b/doc/supported_hw/supported_prog/serprog/300px-HydraFW_Default_PinAssignment.png
new file mode 100644
index 000000000..a9fd931c8
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/300px-HydraFW_Default_PinAssignment.png
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/300px-Serprog_0001.jpeg b/doc/supported_hw/supported_prog/serprog/300px-Serprog_0001.jpeg
new file mode 100644
index 000000000..af1bcafca
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/300px-Serprog_0001.jpeg
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/300px-Teensy31_lpcspi_flasher.jpg b/doc/supported_hw/supported_prog/serprog/300px-Teensy31_lpcspi_flasher.jpg
new file mode 100644
index 000000000..9289aaeac
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/300px-Teensy31_lpcspi_flasher.jpg
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/P1v1_arduino328.png b/doc/supported_hw/supported_prog/serprog/P1v1_arduino328.png
new file mode 100644
index 000000000..0fd808bf0
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/P1v1_arduino328.png
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/P1v2_arduino1280.png b/doc/supported_hw/supported_prog/serprog/P1v2_arduino1280.png
new file mode 100644
index 000000000..7cd6cb9cf
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/P1v2_arduino1280.png
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/P2v1_resdivider.png b/doc/supported_hw/supported_prog/serprog/P2v1_resdivider.png
new file mode 100644
index 000000000..16d5dae19
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/P2v1_resdivider.png
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/P2v2_oc_cs.png b/doc/supported_hw/supported_prog/serprog/P2v2_oc_cs.png
new file mode 100644
index 000000000..45ebe2d41
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/P2v2_oc_cs.png
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/P2v3_buffer4050.png b/doc/supported_hw/supported_prog/serprog/P2v3_buffer4050.png
new file mode 100644
index 000000000..d2ebd8c9d
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/P2v3_buffer4050.png
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/P3v1_dil8_so8_spi.png b/doc/supported_hw/supported_prog/serprog/P3v1_dil8_so8_spi.png
new file mode 100644
index 000000000..3a2f1342e
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/P3v1_dil8_so8_spi.png
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/P3v2_so16_spi.png b/doc/supported_hw/supported_prog/serprog/P3v2_so16_spi.png
new file mode 100644
index 000000000..7ae13796e
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/P3v2_so16_spi.png
Binary files differ
diff --git a/doc/supported_hw/supported_prog/serprog/arduino_flasher.rst b/doc/supported_hw/supported_prog/serprog/arduino_flasher.rst
new file mode 100644
index 000000000..ada05195d
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/arduino_flasher.rst
@@ -0,0 +1,227 @@
+===============
+Arduino flasher
+===============
+
+.. container:: danger, admonition
+
+ **WARNING**
+
+ Make sure that the Arduino SPI voltages and the flash chip voltages matches: Without any extra resistors or level shifter,
+ the Arduino Uno and Duemillanove SPI pins are at 5V, while most chips operate at 3.3v.
+
+Hardware basics
+===============
+
+You'll need to have:
+
+* a supported Arduino, these are
+
+ * any based on the ATmega328 (/168/88 will work with small changes too), like the Arduino Uno R3.
+ * Arduino Mega or Mega2560, but notice that the software has a different branch for them.
+
+* a way to convert the 5V logic levels to 3.3V (except if 3.3V arduino, these are rarer)
+* a 3.3V SPI flash chip that is supported by flashrom
+
+Notes:
+
+* The FTDI based usb-serial converters are the fastest.
+* 1.8V conversion isnt covered here, yet.
+
+There are some simple schematics included here (`source <https://github.com/flashrom/wiki-arduino-spi-example-schematics>`_).
+The idea is that you pick one version from each part 1 through 3, and connect the pin/net names.
+
+Part 1: The Arduino
+-------------------
+
+ATmega328 based ones:
+
+.. image:: P1v1_arduino328.png
+
+For the Arduino Megas:
+
+.. image:: P1v2_arduino1280.png
+
+Part 2: Level translation
+-------------------------
+
+There are a few options here, ranging from the simple resistors (v1) to a buffer chip (v3).
+
+One thing to remember about the resistor dividers is that they're not strong enough to do ISP.
+
+Here's the simple resistors:
+
+.. image:: P2v1_resdivider.png
+
+The part count for the resistor divider is 6 resistors of 2 types or 9 of one type.
+
+Here's one with 5 resistors, the downside is that you'll need to modify the firmware a little:
+
+.. image:: P2v2_oc_cs.png
+
+The 3rd version is using the DIP16 HEF4050 buffer chip:
+
+.. image:: P2v3_buffer4050.png
+
+Part 3: The SPI Flash chip
+--------------------------
+
+The DIL-8 and SOIC-8 versions connect like this:
+
+.. image:: P3v1_dil8_so8_spi.png
+
+For the SMD SOIC-16 chips the pinout is:
+
+.. image:: P3v2_so16_spi.png
+
+Gallery of some flashers
+========================
+
+.. image:: 166px-Serprogduino_v2.jpeg
+
+.. _arduino shield:
+
+Alternative: Shield with SPI and LPC/FWH for 5V Arduinos
+========================================================
+
+.. image:: 250px-Arduino_5V_lpc_spi_shield.jpg
+
+.. image:: 250px-Arduino_lpcspi_shield_render.png
+
+`Firmware and hardware sources <https://github.com/urjaman/frser-m328lpcspi>`_
+
+`Shield PCB shared at oshpark <https://oshpark.com/shared_projects/E6jwmbWy>`_
+
+* This shield and firmware was built for 5V ATMega328s with FTDI, variations to that will need adaptations in building the shield and/or in the firmware.
+ The Uno R3 will work with the fast-usbserial U2 firmware.
+* This shield uses a different pin for SPI CS than the other circuits on this page, and has LPC/FWH capability, thus different firmware.
+ Frser-duino does have the code for using the CS like in this shield, but you need to modify spihw.h.
+* Note: do check for any incompatibilities between your arduino and the shield, eg. the PD7 used as LPC CLK clashes with BT reset in BT arduinos.
+* For LPC/FWH, current (16/02/01) flashrom trunk will be really slow, please use this branch instead.
+
+Software and setup
+==================
+
+The Arduino Uno R3 and other arduinos with an ATmega8U2/16U2 as an usb-serial converter have lots of bugs in their usb-serial firmware
+that prevent it from operating at more than a limited 115200 baud. The frser-duino firmware works around this by default if you use the appropriate make target,
+but there exists a firmware that allows these to be used like the FTDI at 2Mbaud: `fast-usbserial <https://github.com/urjaman/fast-usbserial>`_.
+
+Setup
+-----
+
+Required software
+^^^^^^^^^^^^^^^^^
+
+To make it work you need:
+
+* A recent flashrom with the serprog protocol compiled in (most packaged versions do)
+* `frser-duino which runs on the arduino <https://github.com/urjaman/frser-duino>`_
+
+ * This page used to link to `serprog-duino <https://gitorious.org/gnutoo-personal-arduino-projects/serprog-duino>`_,
+ frser-duino should build in a similar fashion and has better serial buffering and some other features (spi speed setting).
+
+* The avr toolchain(avr-gcc, avr-libc,make etc...)
+
+Building the software
+^^^^^^^^^^^^^^^^^^^^^
+
+First get the firmware source::
+
+ $ git clone --recursive git://github.com/urjaman/frser-duino
+ $ cd frser-duino
+
+Then build it:
+
+For a board with a 8u2 or a 16u2::
+
+ $ make u2 && make flash-u2
+
+For a board with an ftdi::
+
+ $ make ftdi && make flash-ftdi
+
+Building for the Mega1280 or 2560
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As above, except use the branch for the 1280::
+
+ $ git clone --recursive git://github.com/urjaman/frser-duino -b arduino-mega-1280
+
+For the Mega2560, change the Makefile to target the correct MCU (replace 1280 with 2560). Please also verify that the avrdude command is as expected for your device.
+
+Running flashrom
+^^^^^^^^^^^^^^^^
+
+The right flashrom arguments are explained in the :doc:`/classic_cli_manpage`, or here.
+
+Available targets:
+
+* ftdi, flash-ftdi:
+ For the Arduinos with an FTDI
+ compatible flashrom arguments::
+
+ flashrom -p serprog:dev=/dev/ttyUSB0:2000000
+
+ Other boards using an hardware USB<->Serial converter might work too.
+
+* u2, flash-u2:
+ For the Arduino with a 8u2 or a 16u2
+ compatible flashrom arguments::
+
+ flashrom -p serprog:dev=/dev/ttyACM0:115200
+
+So for a board that has an ftdi that would give::
+
+ flashrom -p serprog:dev=/dev/ttyUSB0:2000000
+
+Speed
+^^^^^
+
+The speed is very dependant on the flash chip used:
+
+* Its capacity impacts the speed a lot, as you would expect.
+* The chip model as also a huge impact.
+
+Duemillanove
+^^^^^^^^^^^^
+
+With the duemillanove::
+
+ # time flashrom -p serprog:dev=/dev/ttyUSB0:2000000 -r duemillanove.rom
+ flashrom v0.9.7-r1711 on Linux 3.18.3-gnu-1 (i686)
+ flashrom is free software, get the source code at http://www.flashrom.org
+
+ Calibrating delay loop... delay loop is unreliable, trying to continue OK.
+ serprog: Programmer name is "serprog-duino"
+ Found Winbond flash chip "W25Q32.V" (4096 kB, SPI) on serprog.
+ Reading flash... done.
+ flashrom -p serprog:dev=/dev/ttyUSB0:2000000 -r duemillanove.rom
+
+we have::
+
+ 4.23s user 0.29s system 8% cpu 56.010 total
+
+Uno
+^^^
+
+With the Arduino uno::
+
+ # flashrom -p serprog:dev=/dev/ttyACM0:115200 -r uno.rom
+ flashrom v0.9.7-r1711 on Linux 3.18.3-gnu-1 (i686)
+ flashrom is free software, get the source code at http://www.flashrom.org
+
+ Calibrating delay loop... delay loop is unreliable, trying to continue OK.
+ serprog: Programmer name is "serprog-duino"
+ Found Winbond flash chip "W25Q32.V" (4096 kB, SPI) on serprog.
+ Reading flash... done.
+ flashrom -p serprog:dev=/dev/ttyACM0:115200 -r uno.rom
+
+we have::
+
+ 4.77s user 0.65s system 1% cpu 6:02.43 total
+
+Tested chips
+^^^^^^^^^^^^
+
+* SST25VF016B => huge issues, not recognized by the 3.3v version, had to use the 5v version which is over maximum allowed voltage,
+ also had to lower the serial speed to 115200, ultra slow to write(seem related to the chip itself, since that with the openmoko programmer it's even slower...)...
+* W25X80 works well in 3.3v mode(5v works also but it's highly not advised to use 5v)
diff --git a/doc/supported_hw/supported_prog/serprog/arduino_flasher_3.3v.rst b/doc/supported_hw/supported_prog/serprog/arduino_flasher_3.3v.rst
new file mode 100644
index 000000000..0f4b76cbc
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/arduino_flasher_3.3v.rst
@@ -0,0 +1,237 @@
+====================
+Arduino flasher 3.3v
+====================
+
+Introduction
+============
+
+This explains how to:
+
+* Easily lower the voltage of an arduino
+* Use that arduino to flash a coreboot image on a GM45 Thinkpad with a SOIC16 chip
+
+It requires:
+
+* An AVR Arduino at 5v
+* An USB<->Serial adapter capable of providing enough current to power up:
+
+ * The arduino
+ * The flash chip
+ * The circuits around the flash chip
+
+It was tested with:
+
+* An Arduino.org "nano version 3.3"
+* A Sparkfun "FTDI Basic 3v3" (Uses an FTDI FT232R)
+
+Caveats and warnings:
+
+* It requires you to to never connect an USB cable between the Arduino USB port and the computer while the flasher is connected to a flash chip.
+ This would result in the I/O voltage being 5V instead of 3.3V. If you think you may accidentally connect it this way, this flasher isn't the right solution for you.
+* You need to read the tutorial, if you don't understand it, it's probably not for you. In doubt you could ask for some help in flashrom real-time channels
+ or on the mailing list, see :doc:`/contact`.
+* For now it requires to patch frser-duino
+
+Theory
+========
+
+In the `Atmega328/P datasheet <https://web.archive.org/web/20181004225154/ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf>`_,
+the "32.3. Speed Grades" chapter describes (pages 368 and 369) the link between maximum frequency of the microcontroller and the voltage. At 3.3v, the maximum frequency is 12Mhz.
+
+HOWTO
+========
+
+Build the code installing it on the arduino
+-------------------------------------------
+
+Building frser-duino
+^^^^^^^^^^^^^^^^^^^^
+
+First download frser-duino::
+
+ $ git clone --recursive https://github.com/urjaman/frser-duino.git
+ $ cd frser-duino
+
+Then modify the ``F_CPU`` value in ``main.h`` to be 12Mhz instead of 16Mhz. ``F_CPU`` will look like that::
+
+ #define F_CPU 16000000UL
+
+Change it to::
+
+ #define F_CPU 12000000UL
+
+You can then build the code::
+
+ $ make ftdi
+
+Installing the code on the arduino
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Before installing the code on arduino we want to make sure that we are talking to the right device.
+To do that make sure that the arduino is not connected to your computer and run::
+
+ $ ls -l /dev/ttyUSB0
+
+If everything went fine it will output something like that::
+
+ ls: cannot access '/dev/ttyUSB0': No such file or directory
+
+If instead it looks like that::
+
+ crw-rw---- 1 root uucp 188, 0 27 févr. 14:30 /dev/ttyUSB0
+
+then something else is connected to your computer at ``/dev/ttyUSB0``. If you can't figure what's going on by yourself,
+it's better to try get help on the flashrom channels to fix the issue, see :doc:`/contact`.
+
+Then connect your arduino to the computer and run the same command::
+
+ $ ls -l /dev/ttyUSB0
+
+This time it's supposed to output a line that looks more or less like that::
+
+ crw-rw---- 1 root uucp 188, 0 27 févr. 14:30 /dev/ttyUSB0
+
+At this point we're pretty confident that ``/dev/ttyUSB0`` corresponds to the arduino, so we can install the code with::
+
+ $ make flash-ftdi
+
+Once it is installed we can now test that everything went fine with::
+
+ $ flashrom -p serprog:dev=/dev/ttyUSB0:2000000
+
+This will make flashrom talk to the arduino to verify if everything is fine up to this point.
+
+If everything went fine it will look more or less like that::
+
+ $ flashrom -p serprog:dev=/dev/ttyUSB0:2000000
+ /sys/firmware/dmi/tables/smbios_entry_point: Permission denied
+ /dev/mem: Permission denied
+ /sys/firmware/dmi/tables/smbios_entry_point: Permission denied
+ /dev/mem: Permission denied
+ flashrom v1.0 on Linux 4.15.2-gnu-1 (i686)
+ flashrom is free software, get the source code at https://flashrom.org
+
+ Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
+ serprog: Programmer name is "frser-duino"
+ serprog: requested mapping AT45CS1282 is incompatible: 0x1080000 bytes at 0xfef80000.
+ No EEPROM/flash device found.
+ Note: flashrom can never write if the flash chip isn't found automatically.
+
+This is the important line::
+
+ serprog: Programmer name is "frser-duino"
+
+It means that flashrom is able to talk to the flasher, which reports itself as "frser-duino" We also have the following line::
+
+ No EEPROM/flash device found.
+
+which tells that it didn't find any flash. This is what's supposed to happen since we didn't connect any yet.
+
+Build the programmer
+--------------------
+
+Connect the programmer to the USB<->Serial adapter
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To do that:
+
+* Connect the FTDI adapter RX to the TX of the arduino
+* Connect the FTDI adapter TX to the RX of the arduino
+* Connect the 3V3 of the FTDI adapter to the 5V pin of the Arduino
+* Connect the GND of the FTDI adapter to the GDN of the arduino.
+
+Here's a summary of the above:
+
+======== =========================
+Arduino USB<->Serial port adapter
+======== =========================
+RX TX
+TX RX
+5v 3.3v
+GND GND
+======== =========================
+
+You can now check that the programmer is responding with::
+
+ flashrom -p serprog:dev=/dev/ttyUSB0:2000000
+
+Since you didn't connect yet a flash chip, it will says it found no flash chips::
+
+ $ flashrom -p serprog:dev=/dev/ttyUSB0:2000000
+ /sys/firmware/dmi/tables/smbios_entry_point: Permission denied
+ /dev/mem: Permission denied
+ /sys/firmware/dmi/tables/smbios_entry_point: Permission denied
+ /dev/mem: Permission denied
+ flashrom v1.0 on Linux 4.15.2-gnu-1 (i686)
+ flashrom is free software, get the source code at https://flashrom.org
+
+ Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
+ serprog: Programmer name is "frser-duino"
+ serprog: requested mapping AT45CS1282 is incompatible: 0x1080000 bytes at 0xfef80000.
+ No EEPROM/flash device found.
+ Note: flashrom can never write if the flash chip isn't found automatically.
+
+Again like before the important parts are::
+
+ serprog: Programmer name is "frser-duino"
+
+And::
+
+ No EEPROM/flash device found.
+
+If you made it up to this point, you successfully built the flasher.
+
+Using the programmer
+--------------------
+
+Connect the programmer to a flash chip
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Since the flasher has been built, you probably want to use it.
+
+If you use a clip (Like a SOIC-8 or SOIC16 Pomona clip), connect it to the Arduino
+Connect the chip to the clip, or if you don't use a clip, the chip to the Arduino
+Here's how to connect the flash chips to the programmer:
+
+=========== ========================== =================== =====================
+Arduino pin Function Flash chip pin name SOIC16 Flash chip pin
+=========== ========================== =================== =====================
+D13 CLK (Clock) CLK 16
+D12 MISO (Master In Slave Out) MISO or SO 8
+D11 MOSI (Master Out Slave In) MOSI or SI 15
+D10 CS# (Chip Select) CS# or CS OR SS 7
+GND GND (Ground) GND 10
+5V 3.3V VCC 2
+5V 3.3V WP# (Write Protect) 9
+5V 3.3V HOLD# 1
+=========== ========================== =================== =====================
+
+Then connect an USB cable between the USB<->Serial adapter and the computer.
+Never connect the cable between the Arduino USB port and the computer while the flasher is connected to a flash chip.
+That would result in the I/O voltage being 5V instead of 3.3V.
+
+Flashing
+^^^^^^^^
+
+Run flashrom like that::
+
+ flashrom -p serprog:dev=/dev/ttyUSB0:2000000
+
+With some models of Macronix flash chip (that are present in the Thinkpad X200) you might need to add ``spispeed=100k`` like that::
+
+ flashrom -p serprog:dev=/dev/ttyUSB0:2000000,spispeed=100k
+
+Thanks
+========
+
+Thanks a lot to SwiftGeek on IRC (#libreboot on Libera) for finding the first workaround to make it detect flash chips at lower voltage.
+Thanks also for telling me about the Macronix issues on the Thinkpad X200. This project would not have been possible without that.
+
+Page license
+============
+
+This page is available under the following licenses:
+
+* `CC-BY-SA 3.0 <https://creativecommons.org/licenses/by-sa/3.0/legalcode>`_
+* `CC-BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0/legalcode>`_ or later
+* `GFDL 1.3 <https://www.gnu.org/licenses/fdl-1.3.txt>`_ or later
diff --git a/doc/supported_hw/supported_prog/serprog/index.rst b/doc/supported_hw/supported_prog/serprog/index.rst
new file mode 100644
index 000000000..c1c2d73ea
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/index.rst
@@ -0,0 +1,11 @@
+Serprog
+========
+
+.. toctree::
+ :maxdepth: 1
+
+ overview
+ serprog-protocol
+ arduino_flasher_3.3v
+ arduino_flasher
+ teensy_3_1
diff --git a/doc/supported_hw/supported_prog/serprog/overview.rst b/doc/supported_hw/supported_prog/serprog/overview.rst
new file mode 100644
index 000000000..b274b99b4
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/overview.rst
@@ -0,0 +1,83 @@
+==================
+Serprog (overview)
+==================
+
+This page collects information about the serprog protocol and the programmers implementing it.
+
+Protocol
+========
+
+See :doc:`/supported_hw/supported_prog/serprog/serprog-protocol`. It is designed to be compact and allow efficient storage in limited memory of programmer devices.
+
+AVR flasher by Urja Rannikko
+============================
+
+.. image:: 300px-Avr_rs232_programmer.jpg
+
+The Prototype RS232 AVR parallel flash programmer of Urja Rannikko was the first implementation of the serprog protocol.
+
+The source code can be found `here <https://github.com/urjaman/frser-atmega88>`_.
+
+InSystemFlasher by Juhana Helovuo
+=================================
+
+This was the first one that talks to SPI devices via serial over USB.
+Details can be found in the `coreboot wiki <https://www.coreboot.org/InSystemFlasher>`_ and in this
+`coreboot mailing list thread <https://mail.coreboot.org/pipermail/coreboot/2011-February/063349.html>`_.
+
+atmegaXXu2-flasher by Stefan Tauner
+===================================
+
+Like the InSystemFlasher this one uses LUFA on an AVR microcontroller to tunnel the serial data over USB.
+
+.. image:: 300px-AtmegaXXu2-flasher.jpg
+
+Various Arduino based flashers
+==============================
+
+Frser-duino
+-----------
+
+This project contains `source code <https://github.com/urjaman/frser-duino/>`_ to install on Arduino devices.
+
+This developer also have various ports on `github repo <https://github.com/urjaman?tab=repositories>`_ for several microcontroller boards, such as:
+
+* `frser-teensyflash <https://github.com/urjaman/frser-teensyflash>`_: A port for the teensy microcontroller board
+
+There also various other interesting projects such as:
+
+* `fast-usbserial <https://github.com/urjaman/fast-usbserial>`_: A software to make arduino with 8u2 or 16u2 flashing faster and more reliable]
+* :ref:`arduino shield`
+
+Using a 5v Arduino at 3.3V
+--------------------------
+
+Information on it can be found in this doc: :doc:`/supported_hw/supported_prog/serprog/arduino_flasher_3.3v`
+
+5V arduino with level shifter
+-----------------------------
+
+For detailed instructions on how to use different Arduino models to access SPI flash chips see :doc:`/supported_hw/supported_prog/serprog/arduino_flasher`
+
+.. image:: 300px-Serprog_0001.jpeg
+
+Teensy 3.1 SPI + LPC/FWH Flasher
+--------------------------------
+
+A Teensy 3.1 based small flasher by Urja Rannikko documented here: :doc:`/supported_hw/supported_prog/serprog/teensy_3_1`
+
+HydraBus multi-tool
+-------------------
+
+HydraBus (hardware) with HydraFW (firmware) is an open source multi-tool for learning, developing, debugging, hacking and penetration testing
+of embedded hardware. It is built upon an ARM Cortex-M4 (STM32F405). The source code for HydraFW is available
+`on GitHub <https://github.com/hydrabus/hydrafw>`_. Refer to `their GitHub Wiki <https://github.com/hydrabus/hydrafw/wiki/HydraFW-SPI-guide#flashrom-usage>`_
+for more details on how to use HydraBus with flashrom.
+
+.. image:: 300px-HydraFW_Default_PinAssignment.png
+
+stm32-vserprog by Chi Zhang
+-----------------------------
+
+A powerful option is `stm32-vserprog <https://github.com/dword1511/stm32-vserprog#stm32-vserprog>`_, a firmware for various STM32-based boards
+that turns them into serprog-based programmers with SPI clock speeds up to 36 MHz.
diff --git a/Documentation/serprog-protocol.txt b/doc/supported_hw/supported_prog/serprog/serprog-protocol.rst
index d001cebb1..35574facc 100644
--- a/Documentation/serprog-protocol.txt
+++ b/doc/supported_hw/supported_prog/serprog/serprog-protocol.rst
@@ -1,83 +1,103 @@
-Serial Flasher Protocol Specification - version 1 (0x01 return value == 1)
+=====================================
+Serial Flasher Protocol Specification
+=====================================
+
+Version 1 (0x01 return value == 1)
+==================================
Command And Answer Sequence - all commands give an answer.
+
PC: COMMAND(8bit) <parameters determined by opcode>
+
DEV: ACK/NAK(8bit) <OPTIONAL RETURN BYTES (only if ACK)> / nothing
+
Command 0x10 (SYNCNOP) has a special return of NAK+ACK for synchronization.
ACK = 0x06
+
NAK = 0x15
All multibyte values are little-endian. Addresses and lengths are 24-bit.
-COMMAND Description Parameters Return Value
-0x00 NOP none ACK
-0x01 Query programmer iface version none ACK + 16bit version (nonzero)
-0x02 Query supported commands bitmap none ACK + 32 bytes (256 bits) of supported cmds flags
-0x03 Query programmer name none ACK + 16 bytes string (null padding) / NAK
-0x04 Query serial buffer size none ACK + 16bit size / NAK
-0x05 Query supported bustypes none ACK + 8-bit flags (as per flashrom) / NAK
-0x06 Query connected address lines none ACK + 8bit line count / NAK
-0x07 Query operation buffer size none ACK + 16bit size / NAK
-0x08 Query maximum write-n length none ACK + 24bit length (0==2^24) / NAK
-0x09 Read byte 24-bit addr ACK + BYTE / NAK
-0x0A Read n bytes 24-bit addr + 24-bit length ACK + length bytes / NAK
-0x0B Initialize operation buffer none ACK / NAK
-0x0C Write to opbuf: Write byte 24-bit addr + 8-bit byte ACK / NAK (NOTE: takes 5 bytes in opbuf)
-0x0D Write to opbuf: Write n 24-bit length + 24-bit addr + ACK / NAK (NOTE: takes 7+n bytes in opbuf)
- + length bytes of data
-0x0E Write to opbuf: delay 32-bit usecs ACK / NAK (NOTE: takes 5 bytes in opbuf)
-0x0F Execute operation buffer none ACK / NAK
-0x10 Sync NOP none NAK + ACK (for synchronization)
-0x11 Query maximum read-n length none ACK + 24-bit length (0==2^24) / NAK
-0x12 Set used bustype 8-bit flags (as with 0x05) ACK / NAK
-0x13 Perform SPI operation 24-bit slen + 24-bit rlen ACK + rlen bytes of data / NAK
- + slen bytes of data
-0x14 Set SPI clock frequency in Hz 32-bit requested frequency ACK + 32-bit set frequency / NAK
-0x15 Toggle flash chip pin drivers 8-bit (0 disable, else enable) ACK / NAK
-0x16 Set SPI Chip Select 8-bit ACK / NAK
-0x17 Set SPI Mode 8-bit ACK / NAK
-0x18 Set CS Mode 8-bit ACK / NAK
-0x?? unimplemented command - invalid.
-
+======== =============================== ================================================== =================================================
+COMMAND Description Parameters Return Value
+======== =============================== ================================================== =================================================
+0x00 NOP none ACK
+0x01 Query programmer iface version none ACK + 16bit version (nonzero)
+0x02 Query supported commands bitmap none ACK + 32 bytes (256 bits) of supported cmds flags
+0x03 Query programmer name none ACK + 16 bytes string (null padding) / NAK
+0x04 Query serial buffer size none ACK + 16bit size / NAK
+0x05 Query supported bustypes none ACK + 8-bit flags (as per flashrom) / NAK
+0x06 Query connected address lines none ACK + 8bit line count / NAK
+0x07 Query operation buffer size none ACK + 16bit size / NAK
+0x08 Query maximum write-n length none ACK + 24bit length (0==2^24) / NAK
+0x09 Read byte 24-bit addr ACK + BYTE / NAK
+0x0A Read n bytes 24-bit addr + 24-bit length ACK + length bytes / NAK
+0x0B Initialize operation buffer none ACK / NAK
+0x0C Write to opbuf: Write byte 24-bit addr + 8-bit byte ACK / NAK (NOTE: takes 5 bytes in opbuf)
+0x0D Write to opbuf: Write n 24-bit length + 24-bit addr + length bytes of data ACK / NAK (NOTE: takes 7+n bytes in opbuf)
+0x0E Write to opbuf: delay 32-bit usecs ACK / NAK (NOTE: takes 5 bytes in opbuf)
+0x0F Execute operation buffer none ACK / NAK
+0x10 Sync NOP none NAK + ACK (for synchronization)
+0x11 Query maximum read-n length none ACK + 24-bit length (0==2^24) / NAK
+0x12 Set used bustype 8-bit flags (as with 0x05) ACK / NAK
+0x13 Perform SPI operation 24-bit slen + 24-bit rlen + slen bytes of data ACK + rlen bytes of data / NAK
+0x14 Set SPI clock frequency in Hz 32-bit requested frequency ACK + 32-bit set frequency / NAK
+0x15 Toggle flash chip pin drivers 8-bit (0 disable, else enable) ACK / NAK
+0x16 Set SPI Chip Select 8-bit ACK / NAK
+0x17 Set SPI Mode 8-bit ACK / NAK
+0x18 Set CS Mode 8-bit ACK / NAK
+0x?? unimplemented command - invalid
+======== =============================== ================================================== =================================================
Additional information of the above commands:
+
About unimplemented commands / startup sequence:
Only commands allowed to be used without checking anything are 0x00,0x10 and 0x01 (NOP,SYNCNOP,Q_IFACE).
If 0x01 doesn't return 1, dont do anything if you dont support a newer protocol.
Then, check support for any other opcode (except 0x02) by using 0x02 (Q_CMDMAP).
+
0x02 (Q_CMDMAP):
The map's bits are mapped as follows:
cmd 0 support: byte 0 bit 0
cmd 1 support: byte 0 bit 1
cmd 7 support: byte 0 bit 7
cmd 8 support: byte 1 bit 0, and so on.
+
0x04 (Q_SERBUF):
If the programmer has a guaranteed working flow control,
it should return a big bogus value - eg 0xFFFF.
+
0x05 (Q_BUSTYPE):
The bit's are defined as follows:
bit 0: PARALLEL, bit 1: LPC, bit 2: FWH, bit 3: SPI.
+
0x06 (Q_CHIPSIZE):
Only applicable to parallel programmers.
An LPC/FWH/SPI-programmer can report this as not supported in the command bitmap.
+
0x08 (Q_WRNMAXLEN):
If a programmer reports a bigger maximum write-n length than the serial buffer size,
it is assumed that the programmer can process the data fast enough to take in the
reported maximum write-n without problems.
+
0x0F (O_EXEC):
Execute operation buffer will also clear it, regardless of the return value.
+
0x11 (Q_RDNMAXLEN):
If this command is not supported, assume return of 0 (2^24).
+
0x12 (S_BUSTYPE):
Set's the used bustype if the programmer can support more than one flash protocol.
Sending a byte with more than 1 bit set will make the programmer decide among them
on it's own. Bit values as with Q_BUSTYPE.
+
0x13 (O_SPIOP):
Send and receive bytes via SPI.
Maximum slen is Q_WRNMAXLEN in case Q_BUSTYPE returns SPI only or S_BUSTYPE was used
to set SPI exclusively before. Same for rlen and Q_RDNMAXLEN.
This operation is immediate, meaning it doesn't use the operation buffer.
+
0x14 (S_SPI_FREQ):
Set the SPI clock frequency. The 32-bit value indicates the
requested frequency in Hertz. Value 0 is reserved and should
@@ -86,30 +106,37 @@ Additional information of the above commands:
lower than the one requested. If there is no lower frequency
available the lowest possible should be used. The value
chosen is sent back in the reply with an ACK.
+
0x15 (S_PIN_STATE):
Sets the state of the pin drivers connected to the flash chip. Disabling them allows other
devices (e.g. a mainboard's chipset) to access the chip. This way the serprog controller can
remain attached to the flash chip even when the board is running. The user is responsible to
NOT connect VCC and other permanently externally driven signals to the programmer as needed.
If the value is 0, then the drivers should be disabled, otherwise they should be enabled.
+
0x16 (S_SPI_CS):
Set which SPI Chip Select pin to use. This operation is immediate,
meaning it doesn't use the operation buffer.
+
0x17 (S_SPI_MODE):
Set which SPI Mode to use for 0x13 O_SPIOP commands.
This operation is immediate, meaning it doesn't use the operation buffer.
The current defined modes are:
- 0x00: SPI Half Duplex (default)
- 0x01: SPI Full Duplex
+
+ * 0x00: SPI Half Duplex (default)
+ * 0x01: SPI Full Duplex
+
0x18 (S_CS_MODE):
Set which CS Mode to use. The CS Mode determines the CS behaviour.
This allows manual control over the CS.
This operation is immediate, meaning it doesn't use the operation buffer.
The current defined modes are:
- 0x00: CS Auto Mode. The CS gets selected before 0x13 O_SPIOP commands and
- deselected afterwards. (default)
- 0x01: CS Selected. The CS will be selected until another mode is set.
- 0x02: CS Deselected. The CS will be deselected until another mode is set.
+
+ * 0x00: CS Auto Mode. The CS gets selected before 0x13 O_SPIOP commands and
+ deselected afterwards. (default)
+ * 0x01: CS Selected. The CS will be selected until another mode is set.
+ * 0x02: CS Deselected. The CS will be deselected until another mode is set.
+
About mandatory commands:
The only truly mandatory commands for any device are 0x00, 0x01, 0x02 and 0x10,
but one can't really do anything with these commands.
@@ -120,4 +147,4 @@ Additional information of the above commands:
In addition, support for these commands is recommended:
S_CMD_Q_PGMNAME, S_CMD_Q_BUSTYPE, S_CMD_Q_CHIPSIZE (if parallel).
-See also serprog.c
+See also ``serprog.c``
diff --git a/doc/supported_hw/supported_prog/serprog/teensy_3_1.rst b/doc/supported_hw/supported_prog/serprog/teensy_3_1.rst
new file mode 100644
index 000000000..2336387c5
--- /dev/null
+++ b/doc/supported_hw/supported_prog/serprog/teensy_3_1.rst
@@ -0,0 +1,81 @@
+================================
+Teensy 3.1 SPI + LPC/FWH Flasher
+================================
+
+Note: this was made for the Teensy 3.1, but 3.2 should be compatible too.
+
+Hardware
+========
+
+.. image:: 300px-Teensy31_lpcspi_flasher.jpg
+
+The hardware is made of a `Teensy 3.1 <https://www.pjrc.com/teensy/teensy31.html>`_ and a shield-like PCB over it.
+Schematic and board files for the PCB can be found `in the github <https://github.com/urjaman/frser-teensyflash/tree/master/hardware>`_.
+The PCB is also shared `at OshPark <https://oshpark.com/shared_projects/izukIxq8>`_.
+
+Other components required:
+
+* pin headers (total 28, but get more)
+* a DIL8 socket (if you want to use SPI DIL8)
+* a PLCC32 SMD socket (if you want to use LPC/FWH)
+* optional: small SMD capacitor - pad exists under the shield PCB
+
+Assembly
+--------
+
+* start by installing the SMD cap (if available) and the DIL8 socket on the shield PCB
+* split appropriate strips of pin headers for the teensy and solder them on the teensy, you can use the shield pcb to align them
+
+ * my arrangement was as pictured in order to have more ground clearance under the teensy for the prog button
+
+* push the shield pcb only a little bit on the pin headers, just so the headers dont come over the top of the PCB
+* solder two corner pins to keep the shield PCB in place, these can be done from above
+* solder the rest of headers from the underside while watching that you dont flood the topside with too much solder, especially for the ones close to the PLCC socket
+* in order to solder the SMD PLCC32 socket, you'll need to break out the middle plastic bit, but keep it safe
+
+ * to protect from solder bridges forming between the pin headers and PLCC socket, i placed a very thin tape over the pin header holes on the pcb during the soldering
+ * notice that the PLCC footprint isnt centered on the PCB, meaning dont try to align the PLCC socket exactly on the PCB
+
+* after soldering the PLCC socket, i installed the plastic bit back with a little bit of glue
+
+Software
+========
+
+Firmware for the Teensy is available at https://github.com/urjaman/frser-teensyflash
+
+Also see the README in that directory, both it or this document might be outdated ;)
+
+As of writing the setup would be:
+
+* download arduino, extract it somewhere where you have write access
+* download the `Teensyduino thingy <https://www.pjrc.com/teensy/td_download.html>`_
+* run it on that arduino tree
+* install the udev rules provided in the above url
+* compile and install the `teensy_loader_cli <https://www.pjrc.com/teensy/loader_cli.html>`_ in your path
+
+ ::
+
+ git clone --recursive https://github.com/urjaman/frser-teensyflash.git
+ cd frser-teensyflash
+ nano Makefile # Edit the TEENSYDIR path to include your arduino directory
+ make
+ make program-cli # If this waits you need to press the PROG button on the teensy
+
+After this you should be able to use it with flashrom serprog, for speedups and enhancements to serprog before they're upstreamed
+I'd suggest to use this flashrom tree: https://github.com/urjaman/flashrom/tree/sp-upstream3
+
+Device should be something like /dev/ttyACM0 and the baudrate doesnt matter::
+
+ flashrom -p serprog:dev=/dev/ttyACM0:2000000
+
+ISP Usage
+---------
+
+The same software could be used on a bare teensy 3.1 for ISP SPI programming - this is untested and also the 3.3V supply in the teensy is not strong, so beware, but the SPI pins used would be:
+
+* CS: "Pin 2", PD0
+* SCK: "Pin 14", PD1
+* MOSI: "Pin 7", PD2
+* MISO: "Pin 8", PD3
+
+See https://forum.pjrc.com/threads/25643-Combined-Pin-Assignments-card for a good Teensy pinmap picture.
diff --git a/doc/user_docs/chromebooks.rst b/doc/user_docs/chromebooks.rst
new file mode 100644
index 000000000..feb333b3f
--- /dev/null
+++ b/doc/user_docs/chromebooks.rst
@@ -0,0 +1,8 @@
+=============================
+Documentation for Chromebooks
+=============================
+
+Below is the list of documents and pages that can be useful if you use flashrom on ChromeOS.
+Note these documents are external to flashrom and maintained outside of upstream flashrom tree.
+
+* `Write protection <https://www.chromium.org/chromium-os/developer-library/reference/security/write-protection/>`_
diff --git a/doc/user_docs/index.rst b/doc/user_docs/index.rst
index b4cca3439..5bc93d1b7 100644
--- a/doc/user_docs/index.rst
+++ b/doc/user_docs/index.rst
@@ -6,3 +6,4 @@ Users documentation
fw_updates_vs_spi_wp
example_partial_wp
+ chromebooks
diff --git a/erasure_layout.c b/erasure_layout.c
index 1dd6b6032..e9bfa86c9 100644
--- a/erasure_layout.c
+++ b/erasure_layout.c
@@ -260,29 +260,31 @@ int erase_write(struct flashctx *const flashctx, chipoff_t region_start, chipoff
align_region(erase_layout, flashctx, &region_start, &region_end);
uint8_t *old_start_buf = NULL, *old_end_buf = NULL;
- old_start_buf = (uint8_t *)malloc(old_start - region_start);
- if (!old_start_buf) {
- msg_cerr("Not enough memory!\n");
- ret = -1;
- goto _end;
- }
- old_end_buf = (uint8_t *)malloc(region_end - old_end);
- if (!old_end_buf) {
- msg_cerr("Not enough memory!\n");
- ret = -1;
- goto _end;
- }
+ const size_t start_buf_len = old_start - region_start;
+ const size_t end_buf_len = region_end - old_end;
- if (old_start - region_start) {
- read_flash(flashctx, curcontents + region_start, region_start, old_start - region_start);
- memcpy(old_start_buf, newcontents + region_start, old_start - region_start);
- memcpy(newcontents + region_start, curcontents + region_start, old_start - region_start);
+ if (start_buf_len) {
+ old_start_buf = (uint8_t *)malloc(start_buf_len);
+ if (!old_start_buf) {
+ msg_cerr("Not enough memory!\n");
+ ret = -1;
+ goto _end;
+ }
+ read_flash(flashctx, curcontents + region_start, region_start, start_buf_len);
+ memcpy(old_start_buf, newcontents + region_start, start_buf_len);
+ memcpy(newcontents + region_start, curcontents + region_start, start_buf_len);
}
- if (region_end - old_end) {
+ if (end_buf_len) {
chipoff_t end_offset = old_end + 1;
- read_flash(flashctx, curcontents + end_offset, end_offset, region_end - old_end);
- memcpy(old_end_buf, newcontents + end_offset, region_end - old_end);
- memcpy(newcontents + end_offset, curcontents + end_offset, region_end - old_end);
+ old_end_buf = (uint8_t *)malloc(end_buf_len);
+ if (!old_end_buf) {
+ msg_cerr("Not enough memory!\n");
+ ret = -1;
+ goto _end;
+ }
+ read_flash(flashctx, curcontents + end_offset, end_offset, end_buf_len);
+ memcpy(old_end_buf, newcontents + end_offset, end_buf_len);
+ memcpy(newcontents + end_offset, curcontents + end_offset, end_buf_len);
}
// select erase functions
@@ -381,11 +383,15 @@ int erase_write(struct flashctx *const flashctx, chipoff_t region_start, chipoff
}
_end:
- memcpy(newcontents + region_start, old_start_buf, old_start - region_start);
- memcpy(newcontents + old_end, old_end_buf, region_end - old_end);
+ if (old_start_buf) {
+ memcpy(newcontents + region_start, old_start_buf, start_buf_len);
+ free(old_start_buf);
+ }
- free(old_start_buf);
- free(old_end_buf);
+ if (old_end_buf) {
+ memcpy(newcontents + old_end, old_end_buf, end_buf_len);
+ free(old_end_buf);
+ }
msg_cinfo("Erase/write done from %"PRIx32" to %"PRIx32"\n", region_start, region_end);
return ret;
diff --git a/flashchips.c b/flashchips.c
index 373f28c18..13024de94 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -9374,6 +9374,49 @@ const struct flashchip flashchips[] = {
{
.vendor = "Macronix",
+ .name = "MX25L1633E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1635D,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP ,
+ .tested = TEST_OK_PREWB,
+ .probe = PROBE_SPI_RDID,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = SPI_BLOCK_ERASE_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = SPI_BLOCK_ERASE_D8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = SPI_BLOCK_ERASE_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = SPI_BLOCK_ERASE_C7,
+ }
+ },
+ .printlock = SPI_PRETTYPRINT_STATUS_REGISTER_BP3_SRWD, /* bit6 is quad enable */
+ .unlock = SPI_DISABLE_BLOCKPROTECT_BP3_SRWD,
+ .write = SPI_CHIP_WRITE256,
+ .read = SPI_CHIP_READ, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ .reg_bits =
+ {
+ .srp = {STATUS1, 7, RW},
+ .bp = {{STATUS1, 2, RW}, {STATUS1, 3, RW}, {STATUS1, 4, RW}, {STATUS1, 5, RW}},
+ },
+
+ .decode_range = DECODE_RANGE_SPI25,
+ },
+
+ {
+ .vendor = "Macronix",
.name = "MX25L1635E",
.bustype = BUS_SPI,
.manufacture_id = MACRONIX_ID,
@@ -9612,6 +9655,54 @@ const struct flashchip flashchips[] = {
.decode_range = DECODE_RANGE_SPI25_BIT_CMP,
},
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3239E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3239E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_CFGR | FEATURE_SCUR ,
+ .tested = TEST_OK_PREWB,
+ .probe = PROBE_SPI_RDID,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = SPI_BLOCK_ERASE_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = SPI_BLOCK_ERASE_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = SPI_BLOCK_ERASE_D8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = SPI_BLOCK_ERASE_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = SPI_BLOCK_ERASE_C7,
+ }
+ },
+ .printlock = SPI_PRETTYPRINT_STATUS_REGISTER_BP3_SRWD, /* bit 6 is quad enable */
+ .unlock = SPI_DISABLE_BLOCKPROTECT_BP3_SRWD,
+ .write = SPI_CHIP_WRITE256,
+ .read = SPI_CHIP_READ, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ .reg_bits =
+ {
+ .srp = {STATUS1, 7, RW},
+ .bp = {{STATUS1, 2, RW}, {STATUS1, 3, RW}, {STATUS1, 4, RW}, {STATUS1, 5, RW}},
+ .tb = {CONFIG, 3, OTP},
+ .wps = {SECURITY, 7, OTP}, /* This bit is set by WPSEL command */
+ },
+
+ .decode_range = DECODE_RANGE_SPI25,
+ },
+
{
.vendor = "Macronix",
.name = "MX25L3235D",
@@ -10243,6 +10334,53 @@ const struct flashchip flashchips[] = {
{
.vendor = "Macronix",
+ .name = "MX25R2035F",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25R2035F,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 1024B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_CFGR,
+ .tested = TEST_OK_PREWB,
+ .probe = PROBE_SPI_RDID,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = SPI_BLOCK_ERASE_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = SPI_BLOCK_ERASE_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = SPI_BLOCK_ERASE_D8,
+ }, {
+ .eraseblocks = { {1 * 256 * 1024, 1} },
+ .block_erase = SPI_BLOCK_ERASE_60,
+ }, {
+ .eraseblocks = { {1 * 256 * 1024, 1} },
+ .block_erase = SPI_BLOCK_ERASE_C7,
+ }
+ },
+ .printlock = SPI_PRETTYPRINT_STATUS_REGISTER_BP3_SRWD, /* bit 6 is quad enable */
+ .unlock = SPI_DISABLE_BLOCKPROTECT_BP3_SRWD,
+ .write = SPI_CHIP_WRITE256,
+ .read = SPI_CHIP_READ, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 3600},
+ .reg_bits =
+ {
+ .srp = {STATUS1, 7, RW},
+ .bp = {{STATUS1, 2, RW}, {STATUS1, 3, RW}, {STATUS1, 4, RW}, {STATUS1, 5, RW}},
+ .tb = {CONFIG, 3, OTP}
+ },
+
+ .decode_range = DECODE_RANGE_SPI25,
+ },
+
+ {
+ .vendor = "Macronix",
.name = "MX25R3235F",
.bustype = BUS_SPI,
.manufacture_id = MACRONIX_ID,
diff --git a/flashrom.c b/flashrom.c
index 630c69db8..a36530304 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -2092,7 +2092,7 @@ static int unlock_flash_wp(struct flashctx *const flash,
warn_out:
if (ret)
- msg_cerr("Failed to unlock flash status reg with wp support.\n");
+ msg_cwarn("Failed to unlock flash status reg with wp support.\n");
return ret;
}
@@ -2330,8 +2330,31 @@ int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, co
if (verify && !all_skipped) {
msg_cinfo("Verifying flash... ");
- /* Work around chips which need some time to calm down. */
- programmer_delay(flashctx, 1000*1000);
+ /*
+ * Work around chips which "need some time to calm down."
+ *
+ * Frankly, it's not 100% clear why this delay is here at all,
+ * except for a terse message from 2009 of "a few reports where
+ * verify directly after erase had unpleasant side effects like
+ * corrupting flash or at least getting incorrect verify
+ * results". Ideally, if there were a few known problematic
+ * chips or programmers, we could add quirks flags for those
+ * specific implementations without penalizing all other
+ * flashrom users. But alas, we don't know which systems
+ * experienced those issues.
+ *
+ * Out of an extreme abundance of caution, we retain this
+ * delay, but only for a few non-SPI bus types that were the
+ * likely prevalent targets at the time. This is a complete
+ * guess, which conveniently avoids wasting time on common
+ * BUS_SPI and BUS_PROG systems.
+ *
+ * Background thread:
+ * Subject: RFC: removing 1 second verification delay
+ * https://mail.coreboot.org/hyperkitty/list/flashrom@flashrom.org/thread/SFV3OJBVVMDKRLI3FQA3DDDGEXJ7W4ED/
+ */
+ if (flashctx->chip->bustype & (BUS_PARALLEL | BUS_LPC | BUS_FWH))
+ programmer_delay(flashctx, 1000*1000);
if (verify_all)
combine_image_by_layout(flashctx, newcontents, oldcontents);
diff --git a/include/flashchips.h b/include/flashchips.h
index c9303d589..1e30e84ee 100644
--- a/include/flashchips.h
+++ b/include/flashchips.h
@@ -518,7 +518,7 @@
#define MACRONIX_MX25L6405 0x2017 /* MX25L6405, MX25L6405D (64k 0x20); MX25L6406E/MX25L6408E (4k 0x20); MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E (4k 0x20, 32k 0x52) */
#define MACRONIX_MX25L12805D 0x2018 /* MX25L12805D (no 32k); MX25L12865E, MX25L12835F, MX25L12845E, MX25L12873F, MX25L12833F, MX25L12850F (32k 0x52) */
#define MACRONIX_MX25L25635F 0x2019 /* Same as MX25L25639F, but the latter seems to not support REMS */
-#define MACRONIX_MX25L1635D 0x2415
+#define MACRONIX_MX25L1635D 0x2415 /* MX25L1633E */
#define MACRONIX_MX25L1635E 0x2515 /* MX25L1635{E} */
#define MACRONIX_MX66L51235F 0x201a /* MX66L51235F, MX25L51245G */
#define MACRONIX_MX66L1G45G 0x201b /* MX66L1G45G */
@@ -536,11 +536,13 @@
#define MACRONIX_MX25L6495F 0x9517
#define MACRONIX_MX25L3255E 0x9e16
#define MACRONIX_MX77L25650F 0x7519
+#define MACRONIX_MX25L3239E 0x2536
#define MACRONIX_MX25R1635F 0x2815
#define MACRONIX_MX25R3235F 0x2816
#define MACRONIX_MX25R6435F 0x2817
-#define MACRONIX_MX25R8035F 0x2814
+#define MACRONIX_MX25R2035F 0x2812
+#define MACRONIX_MX25R8035F 0x2814
#define MACRONIX_MX29F001B 0x19
#define MACRONIX_MX29F001T 0x18
diff --git a/meson.build b/meson.build
index c4d7717ff..458b6e882 100644
--- a/meson.build
+++ b/meson.build
@@ -112,6 +112,9 @@ if target_machine.system() == 'dos'
delay_src = files('udelay_dos.c')
endif
srcs += delay_src
+cargs += ['-DCONFIG_DELAY_MINIMUM_SLEEP_US=@0@'.format(
+ get_option('delay_minimum_sleep_us')
+)]
# check for required symbols
if cc.has_function('clock_gettime')
diff --git a/meson_cross/i586_djgpp_dos.txt b/meson_cross/i586_djgpp_dos.txt
index 66d5ed0da..3d97aab7a 100644
--- a/meson_cross/i586_djgpp_dos.txt
+++ b/meson_cross/i586_djgpp_dos.txt
@@ -5,6 +5,11 @@
# Make sure pkg-config can find your self compiles libpci
# or add the path of your libpci.pc as 'pkg_config_libdir'
# under [properies] below.
+#
+# If cross-compiling, you may need to set sys_root in the [properties]
+# section because meson otherwise assumes the same sysroot as the
+# system on which you're building and will get the wrong include files
+# (from /usr/include/x86_64 for example) among other possible issues.
[binaries]
c = 'i586-pc-msdosdjgpp-gcc'
@@ -27,3 +32,4 @@ tests = 'disabled'
ich_descriptors_tool = 'disabled'
[properties]
+sys_root = '/usr/local/djgpp'
diff --git a/meson_options.txt b/meson_options.txt
index e62deb6ee..8a04114da 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -22,3 +22,6 @@ option('man-pages', type : 'feature', value : 'auto', description : 'build the m
option('documentation', type : 'feature', value : 'auto', description : 'build the html documentation')
option('ni845x_search_path', type : 'string', value : 'C:\Program Files (x86)\National Instruments\Ni-845x\MS Visual C',
description : 'Path to search for the proprietary ni845x library and header (32-bit Windows only)')
+option('delay_minimum_sleep_us', type : 'integer', min : 0, value : 100000,
+ description : 'Minimum time in microseconds to suspend execution for (rather than polling) when a delay is required.'
+ + ' Larger values may perform better on machines with low timer resolution, at the cost of increased power.')
diff --git a/tests/udelay.c b/tests/udelay.c
index 277a15dc7..8d24b00dd 100644
--- a/tests/udelay.c
+++ b/tests/udelay.c
@@ -34,6 +34,8 @@ static uint64_t now_us(void) {
#endif
}
+static const int64_t min_sleep = CONFIG_DELAY_MINIMUM_SLEEP_US;
+
/*
* A short delay should delay for at least as long as requested,
* and more than 10x as long would be worrisome.
@@ -43,9 +45,21 @@ static uint64_t now_us(void) {
* test.
*/
void udelay_test_short(void **state) {
+ /*
+ * Delay for 100 microseconds, or short enough that we won't sleep.
+ * It's not useful to test the sleep path because we assume the OS won't
+ * sleep for less time than we ask.
+ */
+ int64_t delay_us = 100;
+ if (delay_us >= min_sleep)
+ delay_us = min_sleep - 1;
+ /* No point in running this test if delay always sleeps. */
+ if (delay_us <= 0)
+ skip();
+
uint64_t start = now_us();
- default_delay(100);
+ default_delay(delay_us);
uint64_t elapsed = now_us() - start;
- assert_in_range(elapsed, 100, 1000);
+ assert_in_range(elapsed, delay_us, 10 * delay_us);
}
diff --git a/udelay.c b/udelay.c
index 453cb34c6..c43b6e3a7 100644
--- a/udelay.c
+++ b/udelay.c
@@ -92,14 +92,15 @@ void internal_sleep(unsigned int usecs)
#endif
}
+static const unsigned min_sleep = CONFIG_DELAY_MINIMUM_SLEEP_US;
+
/* Precise delay. */
void default_delay(unsigned int usecs)
{
- /* If the delay is >0.1 s, use internal_sleep because timing does not need to be so precise. */
- if (usecs > 100000) {
- internal_sleep(usecs);
- } else {
+ if (usecs < min_sleep) {
clock_usec_delay(usecs);
+ } else {
+ internal_sleep(usecs);
}
}
diff --git a/udelay_dos.c b/udelay_dos.c
index 4a29f73d4..c3914eacc 100644
--- a/udelay_dos.c
+++ b/udelay_dos.c
@@ -28,7 +28,7 @@
/* loops per microsecond */
static unsigned long micro = 1;
-__attribute__ ((noinline)) void myusec_delay(unsigned int usecs)
+__attribute__ ((noinline)) static void myusec_delay(unsigned int usecs)
{
unsigned long i;
for (i = 0; i < usecs * micro; i++) {
@@ -153,19 +153,20 @@ void internal_sleep(unsigned int usecs)
usleep(usecs % 1000000);
}
+static const unsigned min_sleep = CONFIG_DELAY_MINIMUM_SLEEP_US;
+
/* Precise delay. */
void default_delay(unsigned int usecs)
{
static bool calibrated = false;
- /* If the delay is >0.1 s, use internal_sleep because timing does not need to be so precise. */
- if (usecs > 100000) {
- internal_sleep(usecs);
- } else {
+ if (usecs < min_sleep) {
if (!calibrated) {
myusec_calibrate_delay();
calibrated = true;
}
myusec_delay(usecs);
+ } else {
+ internal_sleep(usecs);
}
}
diff --git a/util/flashrom_tester/Cargo.toml b/util/flashrom_tester/Cargo.toml
index a76a5b432..50c73dd72 100644
--- a/util/flashrom_tester/Cargo.toml
+++ b/util/flashrom_tester/Cargo.toml
@@ -15,6 +15,9 @@ name = "flashrom_tester"
name = "flashrom_tester"
required-features = ["cli"]
+[workspace]
+members = [".", "flashrom"]
+
[dependencies]
atty = "0.2"
built = { version = "0.5", features = ["chrono"] }
diff --git a/util/flashrom_tester/src/utils.rs b/util/flashrom_tester/src/utils.rs
index 4e8dd7cce..017d77d99 100644
--- a/util/flashrom_tester/src/utils.rs
+++ b/util/flashrom_tester/src/utils.rs
@@ -101,8 +101,9 @@ pub fn construct_layout_file<F: Write>(mut target: F, ls: &LayoutSizes) -> std::
pub fn toggle_hw_wp(dis: bool) -> Result<(), String> {
// The easist way to toggle the hardware write-protect is
- // to {dis}connect the battery (and/or open the WP screw).
+ // to {dis}connect the battery (and/or {open,close} the WP screw).
let s = if dis { "dis" } else { "" };
+ let screw_state = if dis { "open" } else { "close" };
// Print a failure message, but not on the first try.
let mut fail_msg = None;
while dis == get_hardware_wp()? {
@@ -112,7 +113,7 @@ pub fn toggle_hw_wp(dis: bool) -> Result<(), String> {
fail_msg = Some(format!("Hardware write protect is still {}!", !dis));
// The following message is read by the tast test. Do not modify.
info!("Prompt for hardware WP {}able", s);
- eprintln!(" > {}connect the battery (and/or open the WP screw)", s);
+ eprintln!(" > {}connect the battery (and/or {} the WP screw)", s, screw_state);
pause();
}
Ok(())
diff --git a/util/flashrom_udev.rules b/util/flashrom_udev.rules
index 9fd333082..331fee649 100644
--- a/util/flashrom_udev.rules
+++ b/util/flashrom_udev.rules
@@ -93,4 +93,7 @@ ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8a99", MODE="664", GROUP="plugdev"
# Winchiphead (WCH) CH341a based programmer
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="5512", MODE="664", GROUP="plugdev"
+# Winchiphead (WCH) CH347 based programmer
+ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55db", MODE="664", GROUP="plugdev"
+
LABEL="flashrom_rules_end"