diff options
author | Francis Rowe <info@gluglug.org.uk> | 2014-12-23 19:33:45 (EST) |
---|---|---|
committer | Francis Rowe <info@gluglug.org.uk> | 2014-12-23 19:42:02 (EST) |
commit | 8ff050d3893f0115b8bd3f1feda5d032f89fbc32 (patch) | |
tree | 6f8a493c19c2f4bcc59adebb7a88bcea97a7b3ea | |
parent | 1082934d042a5f8b397afc48a0b92edd8d779610 (diff) | |
download | libreboot-8ff050d3893f0115b8bd3f1feda5d032f89fbc32.zip libreboot-8ff050d3893f0115b8bd3f1feda5d032f89fbc32.tar.gz libreboot-8ff050d3893f0115b8bd3f1feda5d032f89fbc32.tar.bz2 |
ich9deblob: Replace makefile (use dependencies)
Use .h and .c files properly. Use header guards. Define function
names in .h files (actual functions in the .c files), and so on.
Move all functions from the .h files to corresponding .c files.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | resources/utilities/ich9deblob/Makefile | 22 | ||||
-rw-r--r-- | resources/utilities/ich9deblob/descriptor/descriptor.c | 128 | ||||
-rw-r--r-- | resources/utilities/ich9deblob/descriptor/descriptor.h | 111 | ||||
-rw-r--r-- | resources/utilities/ich9deblob/gbe/gbe.c | 107 | ||||
-rw-r--r-- | resources/utilities/ich9deblob/gbe/gbe.h | 81 | ||||
-rw-r--r-- | resources/utilities/ich9deblob/main.c (renamed from resources/utilities/ich9deblob/ich9deblob.c) | 6 | ||||
-rw-r--r-- | resources/utilities/ich9deblob/x86compatibility.c | 3 | ||||
-rw-r--r-- | resources/utilities/ich9deblob/x86compatibility.h | 33 |
9 files changed, 306 insertions, 186 deletions
@@ -16,3 +16,4 @@ /resources/utilities/ich9deblob/ich9deblob /resources/utilities/coreboot-libre/tocheck /resources/utilities/ich9deblob/*.o +/resources/utilities/ich9deblob/*/*.o diff --git a/resources/utilities/ich9deblob/Makefile b/resources/utilities/ich9deblob/Makefile index 0a69882..36a892c 100644 --- a/resources/utilities/ich9deblob/Makefile +++ b/resources/utilities/ich9deblob/Makefile @@ -18,10 +18,24 @@ # CC=gcc -CFLAGS=-I. +CFLAGS=-I. -Wall -g -ich9deblob: ich9deblob.c descriptor/descriptor.h gbe/gbe.h - $(CC) $(CFLAGS) ich9deblob.c descriptor/descriptor.h gbe/gbe.h -o ich9deblob +all: ich9deblob + +ich9deblob: main.o descriptor/descriptor.o gbe/gbe.o x86compatibility.o + $(CC) $(CFLAGS) main.o descriptor/descriptor.o gbe/gbe.o x86compatibility.o -o ich9deblob + +main.o: main.c + $(CC) $(CFLAGS) -c main.c -o main.o + +descriptor/descriptor.o: descriptor/descriptor.c + $(CC) $(CFLAGS) -c descriptor/descriptor.c -o descriptor/descriptor.o + +gbe/gbe.o: gbe/gbe.c + $(CC) $(CFLAGS) -c gbe/gbe.c -o gbe/gbe.o + +x86compatibility.o: x86compatibility.c + $(CC) $(CFLAGS) -c x86compatibility.c -o x86compatibility.o clean: - rm -f ich9deblob *.o + rm -f ich9deblob *.o */*.o diff --git a/resources/utilities/ich9deblob/descriptor/descriptor.c b/resources/utilities/ich9deblob/descriptor/descriptor.c new file mode 100644 index 0000000..0e7f2bf --- /dev/null +++ b/resources/utilities/ich9deblob/descriptor/descriptor.c @@ -0,0 +1,128 @@ +/* + * descriptor/descriptor.c + * This file is part of the ich9deblob utility from the libreboot project + * + * Copyright (C) 2014 Steve Shenton <sgsit@libreboot.org> + * Francis Rowe <info@gluglug.org.uk> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Provide descriptor related functions. + */ + +#include <stdio.h> +#include <string.h> + +/* structs describing the data in descriptor region */ +#include "descriptor.h" + +/* + * --------------------------------------------------------------------- + * Descriptor functions + * --------------------------------------------------------------------- + */ + +/* + * Modify the flash descriptor, to remove the ME/AMT, and disable all other regions + * Only Flash Descriptor, Gbe and BIOS regions (BIOS region fills factoryRomSize-12k) are left. + * Tested on ThinkPad X200 and X200S. X200T and other GM45 targets may also work. + * Also described in docs/hcl/x200_remove_me.html + */ +struct DESCRIPTORREGIONRECORD deblobbedDescriptorStructFromFactory(struct DESCRIPTORREGIONRECORD factoryDescriptorStruct, unsigned int factoryRomSize) +{ + struct DESCRIPTORREGIONRECORD deblobbedDescriptorStruct; + memcpy(&deblobbedDescriptorStruct, &factoryDescriptorStruct, DESCRIPTORREGIONSIZE); + + /* + * set number of regions from 4 -> 2 (0 based, so 4 means 5 and 2 + * means 3. We want 3 regions: descriptor, gbe and bios, in that order) + */ + deblobbedDescriptorStruct.flMaps.flMap0.NR = 2; + + /* + * make descriptor writable from OS. This is that the user can run: + * sudo ./flashrom -p internal:laptop=force_I_want_a_brick + * from the OS, without relying an an external SPI flasher, while + * being able to write to the descriptor region (locked by default, + * until making the change below): + */ + deblobbedDescriptorStruct.masterAccessSection.flMstr1.fdRegionWriteAccess = 1; + + /* relocate BIOS region and increase size to fill image */ + deblobbedDescriptorStruct.regionSection.flReg1.BASE = 3; // 3<<FLREGIONBITSHIFT is 12KiB, which is where BIOS region is to begin (after descriptor and gbe) + deblobbedDescriptorStruct.regionSection.flReg1.LIMIT = ((factoryRomSize >> FLREGIONBITSHIFT) - 1); + /* + * ^ for example, 8MB ROM, that's 8388608 bytes. + * ^ 8388608>>FLREGIONBITSHIFT (or 8388608/4096) = 2048 bytes + * 2048 - 1 = 2047 bytes. + * This defines where the final 0x1000 (4KiB) page starts in the flash chip, because the hardware does: + * 2047<<FLREGIONBITSHIFT (or 2047*4096) = 8384512 bytes, or 7FF000 bytes + * (it can't be 0x7FFFFF because of limited number of bits) + */ + + /* set ME region size to 0 - the ME is a blob, we don't want it in libreboot */ + deblobbedDescriptorStruct.regionSection.flReg2.BASE = 0x1FFF; // setting 1FFF means setting size to 0. 1FFF<<FLREGIONBITSHIFT is outside of the ROM image (8MB) size? + /* ^ datasheet says to set this to 1FFF, but FFF was previously used and also worked. */ + deblobbedDescriptorStruct.regionSection.flReg2.LIMIT = 0; + /* + * ^ 0<<FLREGIONBITSHIFT=0, so basically, the size is 0, + * ^ and the base (1FFF>>FLREGIONBITSHIFT) is well outside the higher 8MB range. + */ + + /* relocate Gbe region to begin at 4KiB (immediately after the flash descriptor) */ + deblobbedDescriptorStruct.regionSection.flReg3.BASE = 1; // 1<<FLREGIONBITSHIFT is 4096, which is where the Gbe region is to begin (after the descriptor) + deblobbedDescriptorStruct.regionSection.flReg3.LIMIT = 2; + /* + * ^ 2<<FLREGIONBITSHIFT=8192 bytes. So we are set it to size 8KiB after the first 4KiB in the flash chip. + */ + + /* set Platform region size to 0 - another blob that we don't want */ + deblobbedDescriptorStruct.regionSection.flReg4.BASE = 0x1FFF; // setting 1FFF means setting size to 0. 1FFF<<FLREGIONBITSHIFT is outside of the ROM image (8MB) size? + /* ^ datasheet says to set this to 1FFF, but FFF was previously used and also worked. */ + deblobbedDescriptorStruct.regionSection.flReg4.LIMIT = 0; + /* + * ^ 0<<FLREGIONBITSHIFT=0, so basically, the size is 0, + * and the base (1FFF>>FLREGIONBITSHIFT) is well outside the higher 8MB range. + */ + + /* disable ME in ICHSTRAP0 - the ME is a blob, we don't want it in libreboot */ + deblobbedDescriptorStruct.ichStraps.ichStrap0.meDisable = 1; + + /* disable ME and TPM in MCHSTRAP0 */ + deblobbedDescriptorStruct.mchStraps.mchStrap0.meDisable = 1; // ME is a blob. not wanted in libreboot. + deblobbedDescriptorStruct.mchStraps.mchStrap0.tpmDisable = 1; // not wanted in libreboot + + /* + * disable ME, apart from chipset bugfixes (ME region should first be re-enabled above) + * This is sort of like the CPU microcode updates, but for the chipset + * (commented out below here, since blobs go against libreboot's purpose, + * but may be interesting for others) + * deblobbedDescriptorStruct.mchStraps.mchStrap0.meAlternateDisable = 1; + */ + + /* debugging */ + printf("\nOriginal (factory.rom) Descriptor start block: %08x ; Descriptor end block: %08x\n", factoryDescriptorStruct.regionSection.flReg0.BASE << FLREGIONBITSHIFT, factoryDescriptorStruct.regionSection.flReg0.LIMIT << FLREGIONBITSHIFT); + printf("Original (factory.rom) BIOS start block: %08x ; BIOS end block: %08x\n", factoryDescriptorStruct.regionSection.flReg1.BASE << FLREGIONBITSHIFT, factoryDescriptorStruct.regionSection.flReg1.LIMIT << FLREGIONBITSHIFT); + printf("Original (factory.rom) ME start block: %08x ; ME end block: %08x\n", factoryDescriptorStruct.regionSection.flReg2.BASE << FLREGIONBITSHIFT, factoryDescriptorStruct.regionSection.flReg2.LIMIT << FLREGIONBITSHIFT); + printf("Original (factory.rom) GBe start block: %08x ; GBe end block: %08x\n", factoryDescriptorStruct.regionSection.flReg3.BASE << FLREGIONBITSHIFT, factoryDescriptorStruct.regionSection.flReg3.LIMIT << FLREGIONBITSHIFT); + + printf("\nRelocated (libreboot.rom) Descriptor start block: %08x ; Descriptor end block: %08x\n", deblobbedDescriptorStruct.regionSection.flReg0.BASE << FLREGIONBITSHIFT, deblobbedDescriptorStruct.regionSection.flReg0.LIMIT << FLREGIONBITSHIFT); + printf("Relocated (libreboot.rom) BIOS start block: %08x ; BIOS end block: %08x\n", deblobbedDescriptorStruct.regionSection.flReg1.BASE << FLREGIONBITSHIFT, deblobbedDescriptorStruct.regionSection.flReg1.LIMIT << FLREGIONBITSHIFT); + printf("Relocated (libreboot.rom) ME start block: %08x ; ME end block: %08x\n", deblobbedDescriptorStruct.regionSection.flReg2.BASE << FLREGIONBITSHIFT, deblobbedDescriptorStruct.regionSection.flReg2.LIMIT << FLREGIONBITSHIFT); + printf("Relocated (libreboot.rom) GBe start block: %08x ; GBe end block: %08x\n", deblobbedDescriptorStruct.regionSection.flReg3.BASE << FLREGIONBITSHIFT, deblobbedDescriptorStruct.regionSection.flReg3.LIMIT << FLREGIONBITSHIFT); + + return deblobbedDescriptorStruct; +} diff --git a/resources/utilities/ich9deblob/descriptor/descriptor.h b/resources/utilities/ich9deblob/descriptor/descriptor.h index 847daee..a3dd340 100644 --- a/resources/utilities/ich9deblob/descriptor/descriptor.h +++ b/resources/utilities/ich9deblob/descriptor/descriptor.h @@ -31,9 +31,6 @@ #ifndef DESCRIPTORSTRUCT_H #define DESCRIPTORSTRUCT_H -#include <stdio.h> -#include <string.h> - /* size of the descriptor in bytes */ #define DESCRIPTORREGIONSIZE 0x1000 @@ -45,6 +42,12 @@ */ #define FLREGIONBITSHIFT 0xC +/* + * --------------------------------------------------------------------- + * Descriptor struct representing the data + * --------------------------------------------------------------------- + */ + struct FLVALSIG { unsigned int signature; @@ -75,12 +78,6 @@ struct FLMAP0 */ }; -/* - * --------------------------------------------------------------------- - * Descriptor struct representing the data - * --------------------------------------------------------------------- - */ - struct FLMAP1 { unsigned char FMBA : 8; @@ -255,100 +252,10 @@ struct DESCRIPTORREGIONRECORD { /* * --------------------------------------------------------------------- - * Descriptor functions + * Function declarations (keep gcc/make happy. check them in descriptor.c) * --------------------------------------------------------------------- */ - -/* - * Modify the flash descriptor, to remove the ME/AMT, and disable all other regions - * Only Flash Descriptor, Gbe and BIOS regions (BIOS region fills factoryRomSize-12k) are left. - * Tested on ThinkPad X200 and X200S. X200T and other GM45 targets may also work. - * Also described in docs/hcl/x200_remove_me.html - */ -struct DESCRIPTORREGIONRECORD deblobbedDescriptorStructFromFactory(struct DESCRIPTORREGIONRECORD factoryDescriptorStruct, unsigned int factoryRomSize) -{ - struct DESCRIPTORREGIONRECORD deblobbedDescriptorStruct; - memcpy(&deblobbedDescriptorStruct, &factoryDescriptorStruct, DESCRIPTORREGIONSIZE); - - /* - * set number of regions from 4 -> 2 (0 based, so 4 means 5 and 2 - * means 3. We want 3 regions: descriptor, gbe and bios, in that order) - */ - deblobbedDescriptorStruct.flMaps.flMap0.NR = 2; - - /* - * make descriptor writable from OS. This is that the user can run: - * sudo ./flashrom -p internal:laptop=force_I_want_a_brick - * from the OS, without relying an an external SPI flasher, while - * being able to write to the descriptor region (locked by default, - * until making the change below): - */ - deblobbedDescriptorStruct.masterAccessSection.flMstr1.fdRegionWriteAccess = 1; - - /* relocate BIOS region and increase size to fill image */ - deblobbedDescriptorStruct.regionSection.flReg1.BASE = 3; // 3<<FLREGIONBITSHIFT is 12KiB, which is where BIOS region is to begin (after descriptor and gbe) - deblobbedDescriptorStruct.regionSection.flReg1.LIMIT = ((factoryRomSize >> FLREGIONBITSHIFT) - 1); - /* - * ^ for example, 8MB ROM, that's 8388608 bytes. - * ^ 8388608>>FLREGIONBITSHIFT (or 8388608/4096) = 2048 bytes - * 2048 - 1 = 2047 bytes. - * This defines where the final 0x1000 (4KiB) page starts in the flash chip, because the hardware does: - * 2047<<FLREGIONBITSHIFT (or 2047*4096) = 8384512 bytes, or 7FF000 bytes - * (it can't be 0x7FFFFF because of limited number of bits) - */ - - /* set ME region size to 0 - the ME is a blob, we don't want it in libreboot */ - deblobbedDescriptorStruct.regionSection.flReg2.BASE = 0x1FFF; // setting 1FFF means setting size to 0. 1FFF<<FLREGIONBITSHIFT is outside of the ROM image (8MB) size? - /* ^ datasheet says to set this to 1FFF, but FFF was previously used and also worked. */ - deblobbedDescriptorStruct.regionSection.flReg2.LIMIT = 0; - /* - * ^ 0<<FLREGIONBITSHIFT=0, so basically, the size is 0, - * ^ and the base (1FFF>>FLREGIONBITSHIFT) is well outside the higher 8MB range. - */ - - /* relocate Gbe region to begin at 4KiB (immediately after the flash descriptor) */ - deblobbedDescriptorStruct.regionSection.flReg3.BASE = 1; // 1<<FLREGIONBITSHIFT is 4096, which is where the Gbe region is to begin (after the descriptor) - deblobbedDescriptorStruct.regionSection.flReg3.LIMIT = 2; - /* - * ^ 2<<FLREGIONBITSHIFT=8192 bytes. So we are set it to size 8KiB after the first 4KiB in the flash chip. - */ - - /* set Platform region size to 0 - another blob that we don't want */ - deblobbedDescriptorStruct.regionSection.flReg4.BASE = 0x1FFF; // setting 1FFF means setting size to 0. 1FFF<<FLREGIONBITSHIFT is outside of the ROM image (8MB) size? - /* ^ datasheet says to set this to 1FFF, but FFF was previously used and also worked. */ - deblobbedDescriptorStruct.regionSection.flReg4.LIMIT = 0; - /* - * ^ 0<<FLREGIONBITSHIFT=0, so basically, the size is 0, - * and the base (1FFF>>FLREGIONBITSHIFT) is well outside the higher 8MB range. - */ - - /* disable ME in ICHSTRAP0 - the ME is a blob, we don't want it in libreboot */ - deblobbedDescriptorStruct.ichStraps.ichStrap0.meDisable = 1; - - /* disable ME and TPM in MCHSTRAP0 */ - deblobbedDescriptorStruct.mchStraps.mchStrap0.meDisable = 1; // ME is a blob. not wanted in libreboot. - deblobbedDescriptorStruct.mchStraps.mchStrap0.tpmDisable = 1; // not wanted in libreboot - - /* - * disable ME, apart from chipset bugfixes (ME region should first be re-enabled above) - * This is sort of like the CPU microcode updates, but for the chipset - * (commented out below here, since blobs go against libreboot's purpose, - * but may be interesting for others) - * deblobbedDescriptorStruct.mchStraps.mchStrap0.meAlternateDisable = 1; - */ - - /* debugging */ - printf("\nOriginal (factory.rom) Descriptor start block: %08x ; Descriptor end block: %08x\n", factoryDescriptorStruct.regionSection.flReg0.BASE << FLREGIONBITSHIFT, factoryDescriptorStruct.regionSection.flReg0.LIMIT << FLREGIONBITSHIFT); - printf("Original (factory.rom) BIOS start block: %08x ; BIOS end block: %08x\n", factoryDescriptorStruct.regionSection.flReg1.BASE << FLREGIONBITSHIFT, factoryDescriptorStruct.regionSection.flReg1.LIMIT << FLREGIONBITSHIFT); - printf("Original (factory.rom) ME start block: %08x ; ME end block: %08x\n", factoryDescriptorStruct.regionSection.flReg2.BASE << FLREGIONBITSHIFT, factoryDescriptorStruct.regionSection.flReg2.LIMIT << FLREGIONBITSHIFT); - printf("Original (factory.rom) GBe start block: %08x ; GBe end block: %08x\n", factoryDescriptorStruct.regionSection.flReg3.BASE << FLREGIONBITSHIFT, factoryDescriptorStruct.regionSection.flReg3.LIMIT << FLREGIONBITSHIFT); - - printf("\nRelocated (libreboot.rom) Descriptor start block: %08x ; Descriptor end block: %08x\n", deblobbedDescriptorStruct.regionSection.flReg0.BASE << FLREGIONBITSHIFT, deblobbedDescriptorStruct.regionSection.flReg0.LIMIT << FLREGIONBITSHIFT); - printf("Relocated (libreboot.rom) BIOS start block: %08x ; BIOS end block: %08x\n", deblobbedDescriptorStruct.regionSection.flReg1.BASE << FLREGIONBITSHIFT, deblobbedDescriptorStruct.regionSection.flReg1.LIMIT << FLREGIONBITSHIFT); - printf("Relocated (libreboot.rom) ME start block: %08x ; ME end block: %08x\n", deblobbedDescriptorStruct.regionSection.flReg2.BASE << FLREGIONBITSHIFT, deblobbedDescriptorStruct.regionSection.flReg2.LIMIT << FLREGIONBITSHIFT); - printf("Relocated (libreboot.rom) GBe start block: %08x ; GBe end block: %08x\n", deblobbedDescriptorStruct.regionSection.flReg3.BASE << FLREGIONBITSHIFT, deblobbedDescriptorStruct.regionSection.flReg3.LIMIT << FLREGIONBITSHIFT); - - return deblobbedDescriptorStruct; -} + +struct DESCRIPTORREGIONRECORD deblobbedDescriptorStructFromFactory(struct DESCRIPTORREGIONRECORD factoryDescriptorStruct, unsigned int factoryRomSize); #endif diff --git a/resources/utilities/ich9deblob/gbe/gbe.c b/resources/utilities/ich9deblob/gbe/gbe.c new file mode 100644 index 0000000..b1c55dd --- /dev/null +++ b/resources/utilities/ich9deblob/gbe/gbe.c @@ -0,0 +1,107 @@ +/* + * gbe/gbe.c + * This file is part of the ich9deblob utility from the libreboot project + * + * Copyright (C) 2014 Steve Shenton <sgsit@libreboot.org> + * Francis Rowe <info@gluglug.org.uk> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Provide gbe related functions. + */ + +#include <stdio.h> +#include <string.h> + +/* structs describing the data from gbe region */ +#include "gbe.h" + +/* + * --------------------------------------------------------------------- + * Gbe functions: + * --------------------------------------------------------------------- + */ + +/* Read a 16-bit unsigned int from a supplied region buffer */ +unsigned short gbeGetRegionWordFrom8kBuffer(int index, char* regionData) +{ + return *((unsigned short*)(regionData + (index * 2))); +} + +/* + * checksum calculation for 8k gbe region (algorithm based on datasheet) + * also works for 4k buffers, so long as isBackup remains false + */ +unsigned short gbeGetChecksumFrom8kBuffer(char* regionData, unsigned short desiredValue, char isBackup) +{ + int i; + + unsigned short regionWord; /* store words here for adding to checksum */ + unsigned short checksum = 0; /* this gbe's checksum */ + unsigned short offset = 0; /* in bytes, from the start of the gbe region. */ + + /* + * if isBackup is true, use 2nd gbe region ("backup" region) + * this function uses *word* not *byte* indexes, hence the bit shift. + */ + if (isBackup) offset = GBEREGIONSIZE_4K>>1; + + for (i = 0; i < 0x3F; i++) { + regionWord = gbeGetRegionWordFrom8kBuffer(i+offset, regionData); + checksum += regionWord; + } + checksum = desiredValue - checksum; + return checksum; +} + +/* checksum calculation for 4k gbe struct (algorithm based on datasheet) */ +unsigned short gbeGetChecksumFrom4kStruct(struct GBEREGIONRECORD_4K gbeStruct4k, unsigned short desiredValue) +{ + char gbeBuffer4k[GBEREGIONSIZE_4K]; + memcpy(&gbeBuffer4k, &gbeStruct4k, GBEREGIONSIZE_4K); + return gbeGetChecksumFrom8kBuffer(gbeBuffer4k, desiredValue, 0); +} + +/* modify the gbe region extracted from a factory.rom dump */ +struct GBEREGIONRECORD_8K deblobbedGbeStructFromFactory(struct GBEREGIONRECORD_8K factoryGbeStruct8k) +{ + /* + * Correct the main gbe region. By default, the X200 (as shipped from Lenovo) comes + * with a broken main gbe region, where the backup gbe region is used instead. Modify + * it so that the main region is usable. + */ + + struct GBEREGIONRECORD_8K deblobbedGbeStruct8k; + memcpy(&deblobbedGbeStruct8k, &factoryGbeStruct8k, GBEREGIONSIZE_8K); + + deblobbedGbeStruct8k.backup.checkSum = gbeGetChecksumFrom4kStruct(deblobbedGbeStruct8k.backup, 0xBABA); + memcpy(&deblobbedGbeStruct8k.main, &deblobbedGbeStruct8k.backup, GBEREGIONSIZE_4K); + + /* + * Debugging: + * calculate the 0x3F'th 16-bit uint to make the desired final checksum for GBe + * observed checksum matches (from X200 factory.rom dumps) on main: 0x3ABA 0x34BA 0x40BA. spec defined as 0xBABA. + * X200 ships with a broken main gbe region by default (invalid checksum, and more) + * The "backup" gbe regions on these machines are correct, though, and is what the machines default to + * For libreboot's purpose, we can do much better than that by fixing the main one... below is only debugging + */ + printf("\nfactory Gbe (main): calculated Gbe checksum: 0x%hx and actual GBe checksum: 0x%hx\n", gbeGetChecksumFrom4kStruct(factoryGbeStruct8k.main, 0xBABA), factoryGbeStruct8k.main.checkSum); + printf("factory Gbe (backup) calculated Gbe checksum: 0x%hx and actual GBe checksum: 0x%hx\n", gbeGetChecksumFrom4kStruct(factoryGbeStruct8k.backup, 0xBABA), factoryGbeStruct8k.backup.checkSum); + printf("\ndeblobbed Gbe (main): calculated Gbe checksum: 0x%hx and actual GBe checksum: 0x%hx\n", gbeGetChecksumFrom4kStruct(deblobbedGbeStruct8k.main, 0xBABA), deblobbedGbeStruct8k.main.checkSum); + printf("deblobbed Gbe (backup) calculated Gbe checksum: 0x%hx and actual GBe checksum: 0x%hx\n", gbeGetChecksumFrom4kStruct(deblobbedGbeStruct8k.backup, 0xBABA), deblobbedGbeStruct8k.backup.checkSum); + + return deblobbedGbeStruct8k; +} diff --git a/resources/utilities/ich9deblob/gbe/gbe.h b/resources/utilities/ich9deblob/gbe/gbe.h index 0e3f059..9647d80 100644 --- a/resources/utilities/ich9deblob/gbe/gbe.h +++ b/resources/utilities/ich9deblob/gbe/gbe.h @@ -33,9 +33,6 @@ #ifndef GBESTRUCT_H #define GBESTRUCT_H -#include <stdio.h> -#include <string.h> - /* Size of the full gbe region in bytes */ #define GBEREGIONSIZE_8K 0x2000 /* @@ -80,79 +77,13 @@ struct GBEREGIONRECORD_8K { /* * --------------------------------------------------------------------- - * Gbe functions: + * Function declarations (keep gcc/make happy. check them in gbe.c) * --------------------------------------------------------------------- */ - -/* Read a 16-bit unsigned int from a supplied region buffer */ -unsigned short gbeGetRegionWordFrom8kBuffer(int index, char* regionData) -{ - return *((unsigned short*)(regionData + (index * 2))); -} - -/* - * checksum calculation for 8k gbe region (algorithm based on datasheet) - * also works for 4k buffers, so long as isBackup remains false - */ -unsigned short gbeGetChecksumFrom8kBuffer(char* regionData, unsigned short desiredValue, char isBackup) -{ - int i; - - unsigned short regionWord; /* store words here for adding to checksum */ - unsigned short checksum = 0; /* this gbe's checksum */ - unsigned short offset = 0; /* in bytes, from the start of the gbe region. */ - - /* - * if isBackup is true, use 2nd gbe region ("backup" region) - * this function uses *word* not *byte* indexes, hence the bit shift. - */ - if (isBackup) offset = GBEREGIONSIZE_4K>>1; - - for (i = 0; i < 0x3F; i++) { - regionWord = gbeGetRegionWordFrom8kBuffer(i+offset, regionData); - checksum += regionWord; - } - checksum = desiredValue - checksum; - return checksum; -} - -/* checksum calculation for 4k gbe struct (algorithm based on datasheet) */ -unsigned short gbeGetChecksumFrom4kStruct(struct GBEREGIONRECORD_4K gbeStruct4k, unsigned short desiredValue) -{ - char gbeBuffer4k[GBEREGIONSIZE_4K]; - memcpy(&gbeBuffer4k, &gbeStruct4k, GBEREGIONSIZE_4K); - return gbeGetChecksumFrom8kBuffer(gbeBuffer4k, desiredValue, 0); -} - -/* modify the gbe region extracted from a factory.rom dump */ -struct GBEREGIONRECORD_8K deblobbedGbeStructFromFactory(struct GBEREGIONRECORD_8K factoryGbeStruct8k) -{ - /* - * Correct the main gbe region. By default, the X200 (as shipped from Lenovo) comes - * with a broken main gbe region, where the backup gbe region is used instead. Modify - * it so that the main region is usable. - */ - - struct GBEREGIONRECORD_8K deblobbedGbeStruct8k; - memcpy(&deblobbedGbeStruct8k, &factoryGbeStruct8k, GBEREGIONSIZE_8K); - - deblobbedGbeStruct8k.backup.checkSum = gbeGetChecksumFrom4kStruct(deblobbedGbeStruct8k.backup, 0xBABA); - memcpy(&deblobbedGbeStruct8k.main, &deblobbedGbeStruct8k.backup, GBEREGIONSIZE_4K); - - /* - * Debugging: - * calculate the 0x3F'th 16-bit uint to make the desired final checksum for GBe - * observed checksum matches (from X200 factory.rom dumps) on main: 0x3ABA 0x34BA 0x40BA. spec defined as 0xBABA. - * X200 ships with a broken main gbe region by default (invalid checksum, and more) - * The "backup" gbe regions on these machines are correct, though, and is what the machines default to - * For libreboot's purpose, we can do much better than that by fixing the main one... below is only debugging - */ - printf("\nfactory Gbe (main): calculated Gbe checksum: 0x%hx and actual GBe checksum: 0x%hx\n", gbeGetChecksumFrom4kStruct(factoryGbeStruct8k.main, 0xBABA), factoryGbeStruct8k.main.checkSum); - printf("factory Gbe (backup) calculated Gbe checksum: 0x%hx and actual GBe checksum: 0x%hx\n", gbeGetChecksumFrom4kStruct(factoryGbeStruct8k.backup, 0xBABA), factoryGbeStruct8k.backup.checkSum); - printf("\ndeblobbed Gbe (main): calculated Gbe checksum: 0x%hx and actual GBe checksum: 0x%hx\n", gbeGetChecksumFrom4kStruct(deblobbedGbeStruct8k.main, 0xBABA), deblobbedGbeStruct8k.main.checkSum); - printf("deblobbed Gbe (backup) calculated Gbe checksum: 0x%hx and actual GBe checksum: 0x%hx\n", gbeGetChecksumFrom4kStruct(deblobbedGbeStruct8k.backup, 0xBABA), deblobbedGbeStruct8k.backup.checkSum); - - return deblobbedGbeStruct8k; -} + +unsigned short gbeGetRegionWordFrom8kBuffer(int index, char* regionData); +unsigned short gbeGetChecksumFrom8kBuffer(char* regionData, unsigned short desiredValue, char isBackup); +unsigned short gbeGetChecksumFrom4kStruct(struct GBEREGIONRECORD_4K gbeStruct4k, unsigned short desiredValue); +struct GBEREGIONRECORD_8K deblobbedGbeStructFromFactory(struct GBEREGIONRECORD_8K factoryGbeStruct8k); #endif diff --git a/resources/utilities/ich9deblob/ich9deblob.c b/resources/utilities/ich9deblob/main.c index f223d44..f469f83 100644 --- a/resources/utilities/ich9deblob/ich9deblob.c +++ b/resources/utilities/ich9deblob/main.c @@ -1,5 +1,5 @@ /* - * ich9deblob.c + * main.c * This file is part of the ich9deblob utility from the libreboot project * * Purpose: disable and remove the ME from ich9m/gm45 machines in coreboot. @@ -47,8 +47,8 @@ #include <stdio.h> #include <string.h> #include "descriptor/descriptor.h" /* structs describing what's in the descriptor region */ -#include "gbe/gbe.h" /* structs describing what's in the gbe region, plus functions that use them */ -#include "x86compatibility.c" /* compatibility checks. this utility is not portable yet. */ +#include "gbe/gbe.h" /* structs describing what's in the gbe region */ +#include "x86compatibility.h" /* system/compiler compatibility checks. This code is not portable. */ int main(int argc, char *argv[]) { diff --git a/resources/utilities/ich9deblob/x86compatibility.c b/resources/utilities/ich9deblob/x86compatibility.c index fb0bb73..b37eed6 100644 --- a/resources/utilities/ich9deblob/x86compatibility.c +++ b/resources/utilities/ich9deblob/x86compatibility.c @@ -23,9 +23,8 @@ #include <stdio.h> #include <string.h> - #include "descriptor/descriptor.h" /* structs describing what's in the descriptor region */ -#include "gbe/gbe.h" /* structs describing what's in the gbe region, plus functions that use them */ +#include "gbe/gbe.h" /* structs describing what's in the gbe region */ /* * --------------------------------------------------------------------- diff --git a/resources/utilities/ich9deblob/x86compatibility.h b/resources/utilities/ich9deblob/x86compatibility.h new file mode 100644 index 0000000..bbbfda7 --- /dev/null +++ b/resources/utilities/ich9deblob/x86compatibility.h @@ -0,0 +1,33 @@ +/* + * x86compatibility.h + * This file is part of the ich9deblob utility from the libreboot project + * + * Purpose: keep gcc/make happy. no actual code here, just function definitions. + * + * Copyright (C) 2014 Steve Shenton <sgsit@libreboot.org> + * Francis Rowe <info@gluglug.org.uk> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef X86COMPATIBILITY_H +#define X86COMPATIBILITY_H + +int structSizesIncorrect(struct DESCRIPTORREGIONRECORD descriptorDummy, struct GBEREGIONRECORD_8K gbe8kDummy); +int systemIsBigEndian(); +int structMembersWrongOrder(); +int structBitfieldWrongOrder(); +int systemOrCompilerIncompatible(struct DESCRIPTORREGIONRECORD descriptorStruct, struct GBEREGIONRECORD_8K gbeStruct8k); + +#endif |