summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md187
-rw-r--r--docs/fingerprint/fingerprint.md224
-rw-r--r--docs/sitemap.md5
-rw-r--r--docs/write_protection.md303
4 files changed, 549 insertions, 170 deletions
diff --git a/README.md b/README.md
index 05d0a3e151..2bba5f576b 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,20 @@ and [video](http://youtu.be/Ie7LRGgCXC8) from the
header) is highly recommended for serial console and JTAG access to the EC.
1. A sense of adventure!
+## Terminology
+
+### EC
+
+EC (aka Embedded Controller) can refer to many things in the Chrome OS
+documentation due to historical reasons. If you just see the term "EC", it
+probably refers to "the" EC (i.e. the first one that existed). Most Chrome OS
+devices have an MCU, known as "the EC" that controls lots of things (key
+presses, turning the AP on/off). The OS that was written for "the" EC is now
+running on several different MCUs on Chrome OS devices with various tweaks
+(e.g. the FPMCU, the touchpad one that can do palm rejection, etc.). It's quite
+confusing, so try to be specific and use terms like FPMCU to distinguish the
+fingerprint MCU from "the EC".
+
## Getting the EC code
The code for the EC is open source and is included in the Chromium OS
@@ -554,176 +568,7 @@ addresses are offset.
## Write Protect
-The EC has read-only (RO) and read-write (RW) firmware. Coming out of reset, the
-EC boots into its RO firmware. The RO firmware boots the host and asks it verify
-a hash of the RW firmware (software sync). If the RW firmware is invalid, it is
-updated from a copy in the hosts RW firmware. Once the EC RW firmware is valid,
-the EC jumps to it (without rebooting). The RO firmware is locked in the factory
-and is never changed. The RW firmware can be updated later by pushing a new
-system firmware containing an updated EC RW region.
-
-Note that both the RO and RW firmware regions are normally protected once write
-protect has been turned on. The RW region is unprotected at EC boot until it has
-been verified by the host. The RW region is protected before the Linux kernel is
-loaded.
-
-### Hardware Write Protect
-
-A hardware-based mechanism is used to prevent the RO firmware from being
-changed. The most common design is to have an input grounded by a screw. When
-the screw is inserted, hardware write protect is enabled. This grounded signal
-can be read by the host chipset and EC. It is also routed to the “write protect”
-pin on any SPI flash chips containing firmware.
-
-### Software Write Protect
-
-Software-based write protect state stored in non-volatile memory. If hardware
-write protect is enabled, software write protect can be enabled but can’t be
-disabled. If hardware write protect is disabled, software write protect can be
-enabled or disabled (note that some implementations require an EC reset to
-disable software write protect).
-
-The underlying mechanism implementing software write protect may differ between
-EC chips. However the common requirements are that software write protect can
-only be disabled when hardware write protect is off and that the RO firmware
-must be protected before jumping to RW firmware if protection is enabled.
-
-### `ectool`
-
-`ectool` includes commands to enable and disable software write protect.
-
-#### `ectool flashprotect`
-
-Print out current flash protection state.
-
-```
-Flash protect flags: 0x0000000f wp_gpio_asserted ro_at_boot ro_now all_now
-Valid flags: 0x0000003f wp_gpio_asserted ro_at_boot ro_now all_now STUCK INCONSISTENT
-Writable flags: 0x00000000
-```
-
-`Flash protect flags` - Current flags that are set.
-
-`Valid flags` - All the options for flash protection.
-
-`Writable flags` - The flags that currently can be changed. (In this case, no
-flags can be changed).
-
-Flags:
-
-* `wp_gpio_asserted` - Whether the hardware write protect GPIO is currently
- asserted (read only).
-
-* `ro_at_boot` - Whether the EC will write protect the RO firmware on the next
- boot of the EC.
-
-* `ro_now` - Protect the read-only portion of flash immediately. Requires
- hardware WP be enabled.
-
-* `all_now` - Protect the entire flash (including RW) immediately. Requires
- hardware WP be enabled.
-
-* `STUCK` - Flash protection settings have been fused and can’t be cleared
- (should not happen during normal operation. Read only.)
-
-* `INCONSISTENT` - One or more banks of flash is not protected when it should
- be (should not happen during normal operation. Read only.).
-
-#### `ectool flashprotect enable`
-
-Set `ro_at_boot` flag. The next time the EC is reset it will protect the flash.
-Note that this requires a cold reset.
-
-#### `ectool flashprotect enable now`
-
-Set `ro_at_boot` `ro_now all_now` flags and immediately protect the flash. Note
-that this will fail if hardware write protect is disabled.
-
-#### `ectool flashprotect disable`
-
-Clear `ro_at_boot` flag. This can only be cleared if the EC booted without
-hardware write protect enabled.
-
-Note that you must reset the EC to clear write protect after removing the screw.
-If the `ro_at_boot` flag set and the EC resets with the HW gpio disabled, the EC
-will leave the flash unprotected (`ro_now` and `all_now` flags are not set) but
-leave `ro_at_boot` flag set.
-
-### Flashrom
-
-Flashrom can also be used to query and enable/disable
-[EC flash protection](http://dev.chromium.org/chromium-os/firmware-porting-guide/firmware-ec-write-protection).
-
-#### View the current state of flash protection
-
-```bash
-(chroot) $ flashrom -p ec --wp-status
-```
-
-```
-WP: status: 0x00
-WP: status.srp0: 0
-WP: write protect is disabled.
-WP: write protect range: start=0x00000000, len=0x00000000
-```
-
-#### Enable protection
-
-This is immediate. The protection range indicates the RO region of the firmware.
-
-```bash
-(chroot) $ flashrom -p ec --wp-enable
-```
-
-```
-SUCCESS
-```
-
-```bash
-(chroot) $ flashrom -p ec --wp-status
-```
-
-```
-WP: status: 0x80
-WP: status.srp0: 1
-WP: write protect is enabled.
-WP: write protect range: start=0x00000000, len=0x0001f800
-```
-
-#### Disable protection
-
-Disable can only be done with hardware write protect disabled.
-
-```bash
-(chroot) $ flashrom -p ec --wp-disable
-```
-
-```
-FAILED: RO_AT_BOOT is not clear.
-FAILED
-```
-
-Reboot with screw removed. Note that protection is still enabled but the
-protection range is zero.
-
-```bash
-(chroot) $ flashrom -p ec --wp-status
-```
-
-```
-WP: status: 0x80
-WP: status.srp0: 1
-WP: write protect is enabled.
-WP: write protect range: start=0x00000000, len=0x00000000
-```
-
-```bash
-(chroot) $ flashrom -p ec --wp-disable
-```
-
-```
-SUCCESS
-```
+See [Firmware Write Protection].
## EC Version Strings
@@ -787,3 +632,5 @@ passed as an environment variable `BOARD`:
```
cheese_v1.1.1755-4da9520
```
+
+[Firmware Write Protection]: ./docs/write_protection.md
diff --git a/docs/fingerprint/fingerprint.md b/docs/fingerprint/fingerprint.md
new file mode 100644
index 0000000000..95ddb19e0a
--- /dev/null
+++ b/docs/fingerprint/fingerprint.md
@@ -0,0 +1,224 @@
+# Fingerprint Firmware (FPMCU)
+
+[TOC]
+
+*** note
+NOTE: The build commands assume you are in the `~/trunk/src/platform/ec`
+directory inside the chroot.
+***
+
+*** note
+WARNING: When switching branches in the EC codebase, you probably want to nuke
+the `build` directory or at least the board you're working on: `rm -rf
+build/<board>` or `make clobber` to prevent compilation errors.
+***
+
+## Software
+
+The main source code for fingerprint sensor functionality lives in the
+[`common/fpsensor`] directory.
+
+## Hardware
+
+The following "boards" (specified by the `BOARD` environment variable when
+building the EC code) are for fingerprint:
+
+* [`nocturne_fp`] aka [`nami_fp`] aka [`dartmonkey`] (STM32H743)
+* [`hatch_fp`] aka [`bloonchipper`] (STM32F412)
+ * Support for the STM32F412 for the FPMCU is not yet fully complete, but it
+ is functional enough for testing.
+
+## Building FPMCU Firmware Locally
+
+### See `Makefile` target options
+
+```bash
+(chroot) ~/trunk/src/platform/ec $ make help
+```
+
+### Build
+
+Replace `<BOARD_NAME>` in the command below with the fingerprint MCU that you
+are targeting (e.g., `nocturne_fp`, `dartmonkey`, `bloonchipper`).
+
+```bash
+(chroot) ~/trunk/src/platform/ec $ make BOARD=<BOARD_NAME> -j
+```
+
+### Verbose Build output
+
+Use `V=1` to see the complete compiler output (all flags).
+
+```bash
+(chroot) ~/trunk/src/platform/ec $ make V=1 BOARD=nocturne_fp -j
+```
+
+## Building all EC firmware (before "repo upload")
+
+Before uploading a change to Gerrit via `repo upload`, you'll need to build
+*all* the boards in the EC codebase to make sure your changes do not break any
+others.
+
+*** note
+NOTE: If you forget to do this, do not worry. `repo upload` will warn you and
+prevent you from uploading.
+***
+
+```bash
+(chroot) ~/trunk/src/platform/ec $ make buildall -j
+```
+
+## Build tests
+
+```bash
+(chroot) ~/trunk/src/platform/ec $ make BOARD=nocturne_fp tests-nocturne_fp -j
+```
+
+## Build ectool
+
+```bash
+(chroot) ~/trunk/src/platform/ec $ make BOARD=nocturne_fp utils-host -j
+```
+
+## Build and run the `host_command` fuzz test
+
+```bash
+(chroot) ~/trunk/src/platform/ec $ make BOARD=nocturne_fp run-host_command_fuzz
+```
+
+## Production Updates
+
+### `fp_updater.sh` and `bio_fw_updater`
+
+[`fp_updater.sh`] and [`bio_fw_updater`] are wrappers around [`flashrom`] and
+require already-functioning RO firmware running on the FPMCU. It’s meant to be
+used in production to update the RW firmware. `fp_updater.sh` was used prior to
+M77; `bio_fw_updater` replaces it.
+
+It's also possible to use the updater to update the RO firmware if you disable
+*both* HW and SW write protect, which we use for updating development devices
+that do not have write protect enabled (dogfood devices, EVT, etc.)
+
+In production, only the RW portion of the firmware can be updated (unless the
+user disables [hardware write protection]).
+
+## Factory / RMA / Development Updates
+
+### `flash_fp_mcu`
+
+*** note
+NOTE: This tool is really just for us to use during development or during the
+RMA flow (must go through finalization again in that case). We never update RO
+in the field (can’t by design).
+***
+
+[`flash_fp_mcu`] enables spidev and toggles some GPIOs to put the FPMCU (STM32)
+into bootloader mode. At that point it uses `stm32mon` to rewrite the entire
+flash (both RO and RW). This will only work if [hardware write protection] is
+disabled.
+
+### `stm32mon`
+
+[`stm32mon`] is a tool used to send commands to the STM32 bootloader. We use it
+for development (through `flash_fp_mcu`) to erase and flash the entire chip.
+
+## Keys
+
+The `RO` section of the fingerprint firmware contains the public portion of the
+key used to sign the RW firmware. It uses the public key to validate the
+signature of the RW firmware before jumping to it. It is not possible to
+update the public key stored in the RO firmware once a device has been shipped
+(i.e., once the hardware write protect is enabled).
+
+*** promo
+TODO(tomhughes): Add details about different types of keys (`dev`, `premp`,
+`mp`, etc).
+***
+
+### Resources
+
+* https://sites.google.com/a/google.com/chromeos/resources/engineering/releng/signer-documentation
+* https://sites.google.com/a/google.com/chromeos/paygen---payload
+* https://b.corp.google.com/issues/77882970
+
+## Signing
+
+[`futility`] is used to sign EC firmware. There’s a wrapper script around it
+for signing called [`sign_official_build.sh`].
+
+### Key ID
+
+The output of `futility show` will show a `Public Key File` and `Signature`
+section, each of which have an `ID` field. This ID lets you match the key to the
+signature in case there is more than one.
+[It’s just a sha1sum of the public key,][vboot_key_id] so it lets you
+[uniquely identify the key being used][vb2_public_key].
+
+If you have the key (e.g., in PEM format), you can compute the `ID` with the
+`futility show` command:
+
+```bash
+(chroot) $ futility show ./path/to/key.pem
+```
+
+#### Example
+
+If you are building the `hatch_fp` "board" on your local machine (which signs
+the resulting `ec.bin` with the `dev` key, you can check the `ID` with:
+
+```bash
+(chroot)$ futility show board/hatch_fp/dev_key.pem
+```
+
+```
+Private Key file: board/hatch_fp/dev_key.pem
+ Key length: 3072
+ Key sha1sum: 61382804da86b4156d666cc9a976088f8b647d44
+```
+
+```bash
+(chroot)$ futility show build/hatch_fp/ec.bin
+```
+
+```
+Public Key file: build/hatch_fp/ec.bin
+ Vboot API: 2.1
+ Desc: ""
+ Signature Algorithm: 7 RSA3072EXP3
+ Hash Algorithm: 2 SHA256
+ Version: 0x00000001
+ ID: 61382804da86b4156d666cc9a976088f8b647d44
+Signature: build/hatch_fp/ec.bin
+ Vboot API: 2.1
+ Desc: ""
+ Signature Algorithm: 7 RSA3072EXP3
+ Hash Algorithm: 2 SHA256
+ Total size: 0x1b8 (440)
+ ID: 61382804da86b4156d666cc9a976088f8b647d44
+ Data size: 0x2864c (165452)
+Signature verification succeeded.
+```
+
+### Showing Key ID (fingerprint) for running FW
+
+[Asked on chromeos-chatty-firmware][chatty-firmware-q]
+about adding an EC command to show the Key ID (fingerprint) from the RO version.
+This would make it a lot easier during both development and testing.
+
+[`common/fpsensor`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/refs/heads/master/common/fpsensor/
+[`nocturne_fp`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/refs/heads/master/board/nocturne_fp/
+[`nami_fp`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/refs/heads/master/board/nami_fp/
+[`hatch_fp`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/refs/heads/master/board/hatch_fp/
+[`bloonchipper`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/refs/heads/master/board/bloonchipper/
+[`dartmonkey`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/refs/heads/master/board/dartmonkey/
+[hardware write protection]: ../write_protection.md
+[`flash_fp_mcu`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/master/board/nocturne_fp/flash_fp_mcu
+[`stm32mon`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/e1f3f89e7ea7945adddd0c2e6838f5e59856cff2/util/stm32mon.c#14
+[`futility`]: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/master/futility/
+[`sign_official_build.sh`]: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/master/scripts/image_signing/sign_official_build.sh
+[vboot_key_id]: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/e7db36856ce418552637d1981c173d22dfe5bf39/firmware/2lib/include/2id.h#5
+[vb2_public_key]: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/e7db36856ce418552637d1981c173d22dfe5bf39/firmware/2lib/include/2rsa.h#14
+[chatty-firmware-q]: https://groups.google.com/a/google.com/d/msg/chromeos-chatty-firmware/ZSg423wsFPg/26UbdGwjFQAJ
+[`fp_updater.sh`]: http://go/cros-fp-updater-nocturne-source
+[`bio_fw_updater`]: https://chromium.googlesource.com/chromiumos/platform2/+/refs/heads/master/biod/tools
+[`flashrom`]: https://chromium.googlesource.com/chromiumos/third_party/flashrom/
diff --git a/docs/sitemap.md b/docs/sitemap.md
index 7255a9d873..b1e30c5fd9 100644
--- a/docs/sitemap.md
+++ b/docs/sitemap.md
@@ -4,12 +4,17 @@
* [Getting Started Quickly](./getting_started_quickly.md)
* [Core Runtime](./core_runtime.md)
+* [Write Protection](./write_protection.md)
## Case Closed Debugging (CCD)
* [Case Closed Debugging Overview](./case_closed_debugging.md)
* [Google Security Chip Case Closed Debugging](./case_closed_debugging_cr50.md)
+## Fingerprint MCU (FPMCU)
+
+* [Fingerprint MCU (FPMCU)](./fingerprint/fingerprint.md)
+
## Updaters
* [USB Updater](./usb_updater.md)
diff --git a/docs/write_protection.md b/docs/write_protection.md
new file mode 100644
index 0000000000..fa55801bd3
--- /dev/null
+++ b/docs/write_protection.md
@@ -0,0 +1,303 @@
+# Firmware Write Protection
+
+[TOC]
+
+This is a somewhat tricky topic since write protection implementations can
+differ between chips and the hardware write protection has changed over time,
+so please edit or open a bug if something is not clear.
+
+## Terminology
+
+## RO and RW
+
+MCUs running the EC code have read-only (RO) and read-write (RW) firmware.
+Coming out of reset, the MCU boots into its RO firmware.
+
+In the case of the EC, the RO firmware boots the host and asks it verify a hash
+of the RW firmware (software sync). If the RW firmware is invalid, it is
+updated from a copy in the host's RW firmware.
+
+In the case of the FPMCU, the RO firmware uses the public key embedded in it to
+validate the signature of the RW firmware. If the RW firmware is invalid it
+does not jump to the RW firmware.
+
+Once the RW firmware is validated, the MCU jumps to it (without rebooting). The
+RO firmware is locked in the factory and is never changed. The RW firmware can
+be updated later by pushing a new system firmware containing an updated RW
+region.
+
+Note that both the RO and RW firmware regions are normally protected once write
+protect has been turned on.
+
+In the case of the EC, the RW region is unprotected at MCU boot until it has
+been verified by the host. The RW region is protected before the Linux kernel
+is loaded.
+
+In the case of the FPMCU, the RW region is protected before jumping the RO
+firmware jumps to it.
+
+## Hardware Write Protect {#hw_wp}
+
+On modern Chrome OS devices, the Cr50 (aka GSC / TPM) provides a "hardware
+write protect" GPIO that is connected to the AP SPI flash, EC SPI flash,
+EEPROM, and FPMCU via a [GPIO][write_protect_gpio]. This "hardware write
+protect" can only be disabled with servo or suzyq (["CCD open"]) and
+corresponds to [`OverrideWP`] in ccd. Disabling this write protect disables it
+for everything connected to this signal.
+
+In the case of the FPMCU, the hardware write protect GPIO is tied to the STM32
+`BOOT0` pin, which is what tells the MCU to enter the STM32 bootloader mode.
+
+You may see various references to a [write protect screw in
+documentation][wp_screw]. Older Chrome OS devices had a write protect screw
+that had to be physically removed. More details on this history can be found
+here: http://go/cros-wp-status.
+
+Additional reference:
+https://www.google.com/chromeos/partner/fe/docs/cpfe/firmwaretestmanual.html#hardware-write-protect
+
+## Changing Hardware Write Protection
+
+Modifying the state of hardware write protection (via Cr50 GPIO) can be done
+if the ["CCD open"] process has been completed.
+
+*** note
+`servod` *must* be running for `dut-control` to work. See the [Servo] page for
+details.
+***
+
+### Enable Hardware Write Protection
+
+```bash
+(chroot)$ dut-control fw_wp_state:force_on
+```
+
+### Disable Hardware Write Protection
+
+```bash
+(chroot)$ dut-control fw_wp_state:force_off
+```
+
+### Enable/Disable Hardware Write Protection via Cr50 Console
+
+You can use the following commands from the [Cr50 console]:
+
+```bash
+wp disable
+```
+
+```bash
+wp enable
+```
+
+```bash
+wp follow_batt_pres
+```
+
+## Software Write Protect
+
+Software-based write protect state stored in non-volatile memory. If hardware
+write protect is enabled, software write protect can be enabled but can’t be
+disabled. If hardware write protect is disabled, software write protect can be
+enabled or disabled (note that some implementations require an EC reset to
+disable software write protect).
+
+The underlying mechanism implementing software write protect may differ between
+EC chips. However the common requirements are that software write protect can
+only be disabled when hardware write protect is off and that the RO firmware
+must be protected before jumping to RW firmware if protection is enabled.
+
+*** note
+*WARNING*: If you disable HW write protect *and* then reboot the FPMCU, it will do
+a mass erase of the chip, due to [RDP1](#rdp1).
+***
+
+Additional reference:
+https://www.google.com/chromeos/partner/fe/docs/cpfe/firmwaretestmanual.html#software-write-protect
+
+## Changing Software Write Protection
+
+*** note
+*NOTE*: You cannot disable software write protect if hardware write protect is
+enabled.
+***
+
+Software write protection can be toggled with `ectool --name=cros_fp flashprotect
+enable/disable`, which sends the `EC_CMD_FLASH_PROTECT` command toggling
+`EC_FLASH_PROTECT_RO_AT_BOOT` (changing `--name` to target different ECs).
+
+### Changing Software Write Protection with `ectool`
+
+#### `ectool flashprotect`
+
+Print out current flash protection state.
+
+```
+Flash protect flags: 0x0000000f wp_gpio_asserted ro_at_boot ro_now all_now
+Valid flags: 0x0000003f wp_gpio_asserted ro_at_boot ro_now all_now STUCK INCONSISTENT
+Writable flags: 0x00000000
+```
+
+`Flash protect flags` - Current flags that are set.
+
+`Valid flags` - All the options for flash protection.
+
+`Writable flags` - The flags that currently can be changed. (In this case, no
+flags can be changed).
+
+Flags:
+
+* `wp_gpio_asserted` - Whether the hardware write protect GPIO is currently
+ asserted (read only).
+
+* `ro_at_boot` - Whether the EC will write protect the RO firmware on the next
+ boot of the EC.
+
+* `ro_now` - Protect the read-only portion of flash immediately. Requires
+ hardware WP be enabled.
+
+* `all_now` - Protect the entire flash (including RW) immediately. Requires
+ hardware WP be enabled.
+
+* `STUCK` - Flash protection settings have been fused and can’t be cleared
+ (should not happen during normal operation. Read only.)
+
+* `INCONSISTENT` - One or more banks of flash is not protected when it should
+ be (should not happen during normal operation. Read only.).
+
+#### `ectool flashprotect enable`
+
+Set `ro_at_boot` flag. The next time the EC is reset it will protect the flash.
+Note that this requires a cold reset.
+
+#### `ectool flashprotect enable now`
+
+Set `ro_at_boot` `ro_now all_now` flags and immediately protect the flash. Note
+that this will fail if hardware write protect is disabled.
+
+#### `ectool flashprotect disable`
+
+Clear `ro_at_boot` flag. This can only be cleared if the EC booted without
+hardware write protect enabled.
+
+Note that you must reset the EC to clear write protect after removing the screw.
+If the `ro_at_boot` flag set and the EC resets with the HW gpio disabled, the EC
+will leave the flash unprotected (`ro_now` and `all_now` flags are not set) but
+leave `ro_at_boot` flag set.
+
+### Changing Software Write Protection with `flashrom`
+
+#### View the current state of software write protection
+
+```bash
+(chroot) $ flashrom -p ec --wp-status
+```
+
+```
+WP: status: 0x00
+WP: status.srp0: 0
+WP: write protect is disabled.
+WP: write protect range: start=0x00000000, len=0x00000000
+```
+
+#### Enable software write protection
+
+This is immediate. The protection range indicates the RO region of the firmware.
+
+```bash
+(chroot) $ flashrom -p ec --wp-enable
+```
+
+```
+SUCCESS
+```
+
+```bash
+(chroot) $ flashrom -p ec --wp-status
+```
+
+```
+WP: status: 0x80
+WP: status.srp0: 1
+WP: write protect is enabled.
+WP: write protect range: start=0x00000000, len=0x0001f800
+```
+
+#### Disable software write protection
+
+Disable can only be done with hardware write protect disabled.
+
+```bash
+(chroot) $ flashrom -p ec --wp-disable
+```
+
+```
+FAILED: RO_AT_BOOT is not clear.
+FAILED
+```
+
+Reboot with [hardware write protection](#hw_wp) disabled. Note that protection
+is still enabled but the protection range is zero.
+
+```bash
+(chroot) $ flashrom -p ec --wp-status
+```
+
+```
+WP: status: 0x80
+WP: status.srp0: 1
+WP: write protect is enabled.
+WP: write protect range: start=0x00000000, len=0x00000000
+```
+
+```bash
+(chroot) $ flashrom -p ec --wp-disable
+```
+
+```
+SUCCESS
+```
+
+## `system_is_locked()`
+
+The [`system_is_locked()`] function in the EC code returns false if the HW
+write protect GPIO is disabled or the read-only firmware is not protected.
+
+One way this is used in the FPMCU source is to compile test or debug
+functionality into the firmware. Guarding the test functionality with
+`system_is_locked` allows us to execute the test code in automated testing by
+disabling the hardware write protection; this means we can run the automated
+tests against the exact same firmware we ship, rather than a different version
+that has test functionality compiled in or out.
+
+## RDP1 {#rdp1}
+
+Stands for Readout Protection Level 1.
+
+Protects user flash memory against a debugger (JTAG/SWD) or potential malicious
+code stored in RAM by disabling access (a bus error is generated when read
+access is requested). Otherwise (no debugger connected and no boot in RAM set),
+all read/program/erase operations from/to flash are allowed.
+
+When switching to a lower level of RDP (i.e., setting to 0), the user flash
+memory is mass erased (set to all `0xFF`).
+
+Note that this completely destroys *all* of the firmware, including the RO
+section.
+
+### Additional References
+
+https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1222094
+
+## EC Flash Read/Write Command Write Protection Checks
+
+The EC code command handlers (`command_flash_erase`, `command_flash_write`,
+etc.) return an error if `EC_FLASH_PROTECT_ALL_NOW` is set.
+
+[write_protect_gpio]: https://chromium.googlesource.com/chromiumos/platform/ec/+/aaba1d5efd51082d143ce2ac64e6caf9cb14d5e5/include/ec_commands.h#1599
+["CCD open"]: ./case_closed_debugging_cr50.md#Open-CCD
+[Cr50 console]: ./case_closed_debugging_cr50.md#Consoles
+[`OverrideWP`]: ./case_closed_debugging_cr50.md
+[wp_screw]: https://www.chromium.org/chromium-os/firmware-porting-guide/firmware-ec-write-protection
+[`system_is_locked()`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/aaba1d5efd51082d143ce2ac64e6caf9cb14d5e5/common/system.c#195
+[Servo]: https://www.chromium.org/chromium-os/servo