diff --git a/src/default.nix b/src/default.nix index ca52423..410f15c 100644 --- a/src/default.nix +++ b/src/default.nix @@ -32,6 +32,7 @@ in { kgpe = ownerboot (import ./platform/kgpe); em100 = nixpkgsOnBuildForBuild.callPackage ./util/em100 { }; + flashrom = nixpkgsOnBuildForBuild.callPackage ./flashrom { }; } diff --git a/src/flashrom/0001-implement-wp-enable-disable-for-gigadevice-flash-chi.patch b/src/flashrom/0001-implement-wp-enable-disable-for-gigadevice-flash-chi.patch new file mode 100644 index 0000000..9eab804 --- /dev/null +++ b/src/flashrom/0001-implement-wp-enable-disable-for-gigadevice-flash-chi.patch @@ -0,0 +1,88 @@ +Author: Adam Joseph + + implement --wp-{enable|disable} for gigadevice flash chips + +diff --git a/flashchips.c b/flashchips.c +index 6310c12..ff76cb9 100644 +--- a/flashchips.c ++++ b/flashchips.c +@@ -21,6 +21,7 @@ + #include "flash.h" + #include "flashchips.h" + #include "chipdrivers.h" ++#include "writeprotect.h" + + /** + * List of supported flash chips. +@@ -6342,6 +6343,7 @@ const struct flashchip flashchips[] = { + }, + .printlock = spi_prettyprint_status_register_bp4_srwd, + .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */ ++ .wp = &wp_generic, + .write = spi_chip_write_256, + .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ + .voltage = {1695, 1950}, +diff --git a/writeprotect.c b/writeprotect.c +index b26c121..b304262 100644 +--- a/writeprotect.c ++++ b/writeprotect.c +@@ -130,6 +130,38 @@ enum wp_mode get_wp_mode(const char *mode_str) + return wp_mode; + } + ++// transcribed from "GD25LQ128D DATASHEET v1.8", dated 2019-6-5, Table 1 ++static struct wp_range_descriptor gigadevice_range_descriptors[] = ++ { ++ {.bp = (0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0), .range = { .start = 0x000000, .len = 0, }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(0<<3)|(0<<2)|(0<<1)|(1<<0), .range = { .start = 0xf80000, .len = (0xffffff-0xf80000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0), .range = { .start = 0xf00000, .len = (0xffffff-0xf00000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(0<<3)|(0<<2)|(1<<1)|(1<<0), .range = { .start = 0xe00000, .len = (0xffffff-0xe00000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(0<<3)|(1<<2)|(0<<1)|(0<<0), .range = { .start = 0xfc0000, .len = (0xffffff-0xfc0000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(0<<3)|(1<<2)|(0<<1)|(1<<0), .range = { .start = 0xc00000, .len = (0xffffff-0xc00000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(0<<3)|(1<<2)|(1<<1)|(0<<0), .range = { .start = 0x800000, .len = (0xffffff-0x800000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ ++ {.bp = (0<<4)|(1<<3)|(0<<2)|(0<<1)|(1<<0), .range = { .start = 0x000000, .len = (0x3fffff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(1<<3)|(0<<2)|(1<<1)|(0<<0), .range = { .start = 0x000000, .len = (0x7fffff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(1<<3)|(0<<2)|(1<<1)|(1<<0), .range = { .start = 0x000000, .len = (0x0fffff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0), .range = { .start = 0x000000, .len = (0x1fffff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(1<<3)|(1<<2)|(0<<1)|(1<<0), .range = { .start = 0x000000, .len = (0x3fffff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0), .range = { .start = 0x000000, .len = (0x7fffff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (0<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0), .range = { .start = 0x000000, .len = (0xffffff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ ++ {.bp = (1<<4)|(0<<3)|(0<<2)|(0<<1)|(1<<0), .range = { .start = 0xfff000, .len = (0xffffff-0xfff000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (1<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0), .range = { .start = 0xffe000, .len = (0xffffff-0xffe000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (1<<4)|(0<<3)|(0<<2)|(1<<1)|(1<<0), .range = { .start = 0xffc000, .len = (0xffffff-0xffc000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (1<<4)|(0<<3)|(1<<2)|(0<<1)|(0<<0), .range = { .start = 0xff8000, .len = (0xffffff-0xff8000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (1<<4)|(0<<3)|(1<<2)|(0<<1)|(1<<0), .range = { .start = 0xff8000, .len = (0xffffff-0xff8000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ ++ {.bp = (1<<4)|(1<<3)|(0<<2)|(0<<1)|(1<<0), .range = { .start = 0x000000, .len = (0x000fff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (1<<4)|(1<<3)|(0<<2)|(1<<1)|(0<<0), .range = { .start = 0x000000, .len = (0x001fff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (1<<4)|(1<<3)|(0<<2)|(1<<1)|(1<<0), .range = { .start = 0x000000, .len = (0x003fff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0), .range = { .start = 0x000000, .len = (0x007fff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }}, ++ {.bp = (1<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0), .range = { .start = 0x000000, .len = (0x007fff-0x000000+1), }, .m = { .sec = 0, .tb = 3, }} ++ }; ++ + /* Given a flash chip, this function returns its writeprotect info. */ + static int generic_range_table(const struct flashctx *flash, + struct wp_context **wp, +@@ -139,6 +171,20 @@ static int generic_range_table(const struct flashctx *flash, + *num_entries = 0; + + switch (flash->chip->manufacture_id) { ++ case 0xc8: { ++ *wp = malloc(sizeof(struct wp_context)); ++ (*wp)->sr1.bp0_pos = 2; ++ (*wp)->sr1.bp_bits = 5; ++ (*wp)->sr1.srp_pos = 7; ++ (*wp)->get_modifier_bits = NULL; ++ (*wp)->set_modifier_bits = NULL; ++ *num_entries = 24; ++ (*wp)->descrs = malloc((*num_entries) * sizeof(struct wp_range_descriptor)); ++ for(int i=0; i<*num_entries; i++) { ++ (*wp)->descrs[i] = gigadevice_range_descriptors[i]; ++ } ++ break; ++ } + default: + msg_cerr("%s: flash vendor (0x%x) not found, aborting\n", + __func__, flash->chip->manufacture_id); diff --git a/src/flashrom/default.nix b/src/flashrom/default.nix new file mode 100644 index 0000000..4cd9748 --- /dev/null +++ b/src/flashrom/default.nix @@ -0,0 +1,37 @@ +{ stdenv +, lib +, fetchFromGitHub +, installShellFiles +, libftdi1 +, libusb1 +, pciutils +, pkg-config +}: + +stdenv.mkDerivation { + pname = "flashrom"; + version = "1.2+wp"; + + src = fetchFromGitHub { + owner = "flashrom"; + repo = "flashrom"; + rev = "cd9b7b427d19e591c1091cb783a51951ef3aeffc"; + sha256 = "sha256-gK/z+WkEHFmT/dYnNLMn4Cb2ESBfqipc19ZVxmaZabQ="; + }; + + nativeBuildInputs = [ pkg-config installShellFiles ]; + buildInputs = lib.optional (!stdenv.hostPlatform.isStatic) libftdi1 + ++ [ libusb1 pciutils ]; + + patches = [ + ./0001-implement-wp-enable-disable-for-gigadevice-flash-chi.patch + ]; + + makeFlags = [ "PREFIX=$(out)" "libinstall" ]; + + meta = with lib; { + homepage = "https://www.flashrom.org"; + description = "Utility for reading, writing, erasing and verifying flash ROM chips"; + license = licenses.gpl2; + }; +}