From 1b5c10a8c08a5c5d5c43c02dddbedd6961fbf2e4 Mon Sep 17 00:00:00 2001 From: Francis Rowe Date: Tue, 23 Dec 2014 17:03:26 -0500 Subject: ich9deblob: unify comment styling --- diff --git a/resources/utilities/ich9deblob/descriptor/descriptor.h b/resources/utilities/ich9deblob/descriptor/descriptor.h index a93c996..847daee 100644 --- a/resources/utilities/ich9deblob/descriptor/descriptor.h +++ b/resources/utilities/ich9deblob/descriptor/descriptor.h @@ -19,12 +19,14 @@ * along with this program. If not, see . */ -// Purpose: provide struct representing descriptor region. -// Map actual buffers of this regions, directly to instances of these -// structs. This makes working with descriptor really easy. - -// bit fields used, corresponding to datasheet. See links to datasheets -// and documentation in ich9deblob.c +/* + * Purpose: provide struct representing descriptor region. + * Map actual buffers of this regions, directly to instances of these + * structs. This makes working with descriptor really easy. + * + * bit fields used, corresponding to datasheet. See links to datasheets + * and documentation in ich9deblob.c + */ #ifndef DESCRIPTORSTRUCT_H #define DESCRIPTORSTRUCT_H @@ -32,42 +34,55 @@ #include #include -#define DESCRIPTORREGIONSIZE 0x1000 // 4 KiB +/* size of the descriptor in bytes */ +#define DESCRIPTORREGIONSIZE 0x1000 -// Related to the flash descriptor -#define FLREGIONBITSHIFT 0xC // bits 12(0xC)-24(0x18) are represented for words found in the flash descriptor - // To manipulate these easily in C, we shift them by FLREGIONBITSHIFT and then shift them back when done +/* + * Related to the flash descriptor + * bits 12(0xC)-24(0x18) are represented for words found in the flash descriptor + * To manipulate these easily in C, we shift them by FLREGIONBITSHIFT and then shift them back when done + * (because this is how data is stored in the flash descriptor) + */ +#define FLREGIONBITSHIFT 0xC -struct FLVALSIG{ +struct FLVALSIG +{ unsigned int signature; }; -struct FLMAP0 { - // least signicant bits +struct FLMAP0 +{ + /* least signicant bits */ unsigned char FCBA : 8; unsigned char NC : 2; unsigned char reserved1 : 6; - // ^^^^ unnamed members like these represent unused bits (per datasheet). - // the same applies for all structs in this file. + /* + * ^^^^ unnamed members like these represent unused bits (per datasheet). + * the same applies for all structs in this file. + */ unsigned char FRBA : 8; unsigned char NR : 3; unsigned char reserved2 : 5; - // most significant bits. - - // the datasheet lists msb's first and lsb's last, in each table. - // meanwhile, x86 gcc treats the members at the top of the struct as lsb's - // and at the bottom of the struct, the members there are msb's. The same - // fact applies to all the other structs below. + /* most significant bits. */ - // non-x86 (and/or non-gcc) is untested - // little endian assumed + /* + * the datasheet lists msb's first and lsb's last, in each table. + * meanwhile, x86 gcc treats the members at the top of the struct as lsb's + * and at the bottom of the struct, the members there are msb's. The same + * fact applies to all the other structs below. + * + * non-x86 (and/or non-gcc) is untested. little endian assumed. + */ }; -// --------------------------------------------------------------------- -// Descriptor struct representing the data -// --------------------------------------------------------------------- +/* + * --------------------------------------------------------------------- + * Descriptor struct representing the data + * --------------------------------------------------------------------- + */ -struct FLMAP1 { +struct FLMAP1 +{ unsigned char FMBA : 8; unsigned char NM : 3; unsigned char reserved : 5; @@ -75,19 +90,22 @@ struct FLMAP1 { unsigned char ISL : 8; }; -struct FLMAP2 { +struct FLMAP2 +{ unsigned char FMSBA : 8; unsigned char MSL : 8; unsigned short reserved : 16; }; -struct FLMAPS { +struct FLMAPS +{ struct FLMAP0 flMap0; struct FLMAP1 flMap1; struct FLMAP2 flMap2; }; -struct FLCOMP { +struct FLCOMP +{ unsigned char component1Density : 3; unsigned char component2Density : 3; unsigned char reserved1 : 2; @@ -101,26 +119,29 @@ struct FLCOMP { unsigned char reserved4 : 2; }; -struct COMPONENTSECTIONRECORD { +struct COMPONENTSECTIONRECORD +{ struct FLCOMP flcomp; unsigned int flill; unsigned int flpb; unsigned char padding[36]; }; -struct FLREG { +struct FLREG +{ unsigned short BASE : 13; unsigned short reserved1 : 3; unsigned short LIMIT : 13; unsigned short reserved2 : 3; }; -struct REGIONSECTIONRECORD { - struct FLREG flReg0; // Descriptor - struct FLREG flReg1; // BIOS - struct FLREG flReg2; // ME - struct FLREG flReg3; // Gbe - struct FLREG flReg4; // Platform +struct REGIONSECTIONRECORD +{ + struct FLREG flReg0; /* Descriptor */ + struct FLREG flReg1; /* BIOS */ + struct FLREG flReg2; /* ME */ + struct FLREG flReg3; /* Gbe */ + struct FLREG flReg4; /* Platform */ unsigned char padding[12]; }; @@ -149,28 +170,28 @@ struct MASTERACCESSSECTIONRECORD { }; struct ICHSTRAP0 { - // todo: add MeSmBus2Sel (boring setting) - unsigned char meDisable : 1; // If true, ME is disabled. + /* todo: add MeSmBus2Sel (boring setting) */ + unsigned char meDisable : 1; /* If true, ME is disabled. */ unsigned char reserved1 : 6; - unsigned char tcoMode : 1; // TCO Mode: (Legacy,TCO Mode) The TCO Mode, along with the BMCMODE strap, determines the behavior of the IAMT SmBus controller. - unsigned char smBusAddress : 7; // The ME SmBus 7-bit address. - unsigned char bmcMode : 1; // BMC mode: If true, device is in BMC mode. If Intel(R) AMT or ASF using Intel integrated LAN then this should be false. - unsigned char tripPointSelect : 1; // Trip Point Select: false the NJCLK input buffer is matched to 3.3v signal from the external PHY device, true is matched to 1.8v. + unsigned char tcoMode : 1; /* TCO Mode: (Legacy,TCO Mode) The TCO Mode, along with the BMCMODE strap, determines the behavior of the IAMT SmBus controller. */ + unsigned char smBusAddress : 7; /* The ME SmBus 7-bit address. */ + unsigned char bmcMode : 1; /* BMC mode: If true, device is in BMC mode. If Intel(R) AMT or ASF using Intel integrated LAN then this should be false. */ + unsigned char tripPointSelect : 1; /* Trip Point Select: false the NJCLK input buffer is matched to 3.3v signal from the external PHY device, true is matched to 1.8v. */ unsigned char reserved2 : 2; - unsigned char integratedGbe : 1; // Integrated GbE or PCI Express select: (PCI Express,,Integrated GbE) Defines what PCIe Port 6 is used for. - unsigned char lanPhy : 1; // LANPHYPC_GP12_SEL: Set to 0 for GP12 to be used as GPIO (General Purpose Input/Output), or 1 for GP12 to be used for native mode as LAN_PHYPC for 82566 LCD device + unsigned char integratedGbe : 1; /* Integrated GbE or PCI Express select: (PCI Express,,Integrated GbE) Defines what PCIe Port 6 is used for. */ + unsigned char lanPhy : 1; /* LANPHYPC_GP12_SEL: Set to 0 for GP12 to be used as GPIO (General Purpose Input/Output), or 1 for GP12 to be used for native mode as LAN_PHYPC for 82566 LCD device */ unsigned char reserved3 : 3; - unsigned char dmiRequesterId : 1; // DMI requestor ID security check disable: The primary purpose of this strap is to support server environments with multiple CPUs that each have a different RequesterID that can access the Flash. - unsigned char smBus2Address : 7; // The ME SmBus 2 7-bit address. + unsigned char dmiRequesterId : 1; /* DMI requestor ID security check disable: The primary purpose of this strap is to support server environments with multiple CPUs that each have a different RequesterID that can access the Flash. */ + unsigned char smBus2Address : 7; /* The ME SmBus 2 7-bit address. */ }; struct ICHSTRAP1 { - unsigned char northMlink : 1; // North MLink Dynamic Clock Gate Disable : Sets the default value for the South MLink Dynamic Clock Gate Enable registers. - unsigned char southMlink : 1; // South MLink Dynamic Clock Gate Enable : Sets the default value for the South MLink Dynamic Clock Gate Enable registers. - unsigned char meSmbus : 1; // ME SmBus Dynamic Clock Gate Enable : Sets the default value for the ME SMBus Dynamic Clock Gate Enable for both the ME SmBus controllers. - unsigned char sstDynamic : 1; // SST Dynamic Clock Gate Enable : Sets the default value for the SST Clock Gate Enable registers. + unsigned char northMlink : 1; /* North MLink Dynamic Clock Gate Disable : Sets the default value for the South MLink Dynamic Clock Gate Enable registers. */ + unsigned char southMlink : 1; /* South MLink Dynamic Clock Gate Enable : Sets the default value for the South MLink Dynamic Clock Gate Enable registers. */ + unsigned char meSmbus : 1; /* ME SmBus Dynamic Clock Gate Enable : Sets the default value for the ME SMBus Dynamic Clock Gate Enable for both the ME SmBus controllers. */ + unsigned char sstDynamic : 1; /* SST Dynamic Clock Gate Enable : Sets the default value for the SST Clock Gate Enable registers. */ unsigned char reserved1 : 4; - unsigned char northMlink2 : 1; // North MLink 2 Non-Posted Enable : 'true':North MLink supports two downstream non-posted requests. 'false':North MLink supports one downstream non-posted requests. + unsigned char northMlink2 : 1; /* North MLink 2 Non-Posted Enable : 'true':North MLink supports two downstream non-posted requests. 'false':North MLink supports one downstream non-posted requests. */ unsigned char reserved2 : 7; unsigned short reserved3 : 16; }; @@ -183,12 +204,12 @@ struct ICHSTRAPSRECORD { }; struct MCHSTRAP0 { - unsigned char meDisable : 1; // If true, ME is disabled. - unsigned char meBootFromFlash : 1; // ME boot from Flash - guessed location - unsigned char tpmDisable : 1; // iTPM Disable : When set true, iTPM Host Interface is disabled. When set false (default), iTPM is enabled. + unsigned char meDisable : 1; /* If true, ME is disabled. */ + unsigned char meBootFromFlash : 1; /* ME boot from Flash - guessed location */ + unsigned char tpmDisable : 1; /* iTPM Disable : When set true, iTPM Host Interface is disabled. When set false (default), iTPM is enabled. */ unsigned char reserved1 : 3; - unsigned char spiFingerprint : 1; // SPI Fingerprint Sensor Present: Indicates if an SPI Fingerprint sensor is present at CS#1. - unsigned char meAlternateDisable : 1; // ME Alternate Disable: Setting this bit allows ME to perform critical chipset functions but prevents loading of any ME FW applications. + unsigned char spiFingerprint : 1; /* SPI Fingerprint Sensor Present: Indicates if an SPI Fingerprint sensor is present at CS#1. */ + unsigned char meAlternateDisable : 1; /* ME Alternate Disable: Setting this bit allows ME to perform critical chipset functions but prevents loading of any ME FW applications. */ unsigned char reserved2 : 8; unsigned short reserved3 : 16; }; @@ -232,74 +253,91 @@ struct DESCRIPTORREGIONRECORD { struct OEMSECTIONRECORD oemSection; }; -// --------------------------------------------------------------------- -// Descriptor functions -// --------------------------------------------------------------------- +/* + * --------------------------------------------------------------------- + * 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. +/* + * 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); - - // Now we need to modify the descriptor so that the ME can be excluded - // from the final ROM image (libreboot one) after adding the modified - // descriptor+gbe. Refer to libreboot docs for details: docs/hcl/x200_remove_me.html - // 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) + /* + * 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): + /* + * 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 + /* relocate BIOS region and increase size to fill image */ deblobbedDescriptorStruct.regionSection.flReg1.BASE = 3; // 3<> 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 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) is well outside the higher 8MB range. + /* + * ^ 0<>FLREGIONBITSHIFT) is well outside the higher 8MB range. + */ - // relocate Gbe region to begin at 4KiB (immediately after the flash descriptor) + /* relocate Gbe region to begin at 4KiB (immediately after the flash descriptor) */ deblobbedDescriptorStruct.regionSection.flReg3.BASE = 1; // 1<>FLREGIONBITSHIFT) is well outside the higher 8MB range. + /* + * ^ 0<>FLREGIONBITSHIFT) is well outside the higher 8MB range. + */ - // disable ME in ICHSTRAP0 - the ME is a blob, we don't want it in libreboot + /* 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 + /* 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; + /* + * 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 + /* 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); diff --git a/resources/utilities/ich9deblob/gbe/gbe.h b/resources/utilities/ich9deblob/gbe/gbe.h index b775534..de3b27d 100644 --- a/resources/utilities/ich9deblob/gbe/gbe.h +++ b/resources/utilities/ich9deblob/gbe/gbe.h @@ -19,12 +19,16 @@ * along with this program. If not, see . */ -// Purpose: provide struct representing gbe region. -// Map actual buffers of this regions, directly to instances of these -// structs. This makes working with gbe really easy. +/* + * Purpose: provide struct representing gbe region. + * Map actual buffers of this regions, directly to instances of these + * structs. This makes working with gbe really easy. + */ -// bit fields used, corresponding to datasheet. See links to datasheets -// and documentation in ich9deblob.c +/* + * bit fields used, corresponding to datasheet. See links to datasheets + * and documentation in ich9deblob.c + */ #ifndef GBESTRUCT_H #define GBESTRUCT_H @@ -32,55 +36,70 @@ #include #include -#define GBEREGIONSIZE 0x2000 // 8 KiB -// These will have a modified descriptor+gbe based on what's in the factory.rom -// These will be joined into a single 12KiB buffer (descriptor, then gbe) and saved to a file -// NOTE: The GBE region of 8K is actually 2x 4K regions in a single region; both 4K blocks can be identical (and by default, are) -// The 2nd one is a "backup", but we don't know when it's used. perhaps it's used when the checksum on the first one does not match? +/* Size of gbe region in bytes */ +#define GBEREGIONSIZE 0x2000 -// --------------------------------------------------------------------- -// Gbe struct representing the data -// --------------------------------------------------------------------- +/* + * These will have a modified descriptor+gbe based on what's in the factory.rom + * These will be joined into a single 12KiB buffer (descriptor, then gbe) and saved to a file + * NOTE: The GBE region of 8K is actually 2x 4K regions in a single region; both 4K blocks can be identical (and by default, are) + * The 2nd one is a "backup", but we don't know when it's used. perhaps it's used when the checksum on the first one does not match? + */ + +/* + * --------------------------------------------------------------------- + * Gbe struct representing the data: + * --------------------------------------------------------------------- + */ struct GBEREGIONRECORD_4K { - unsigned char macAddress[6]; // 0x03 words, or 0x06 bytes - unsigned char otherStuff[120]; // 0x3c words, or 0x7E bytes - unsigned short checkSum; // when added to the sum of all words above, this should be 0xBABA + unsigned char macAddress[6]; /* 0x03 words, or 0x06 bytes */ + unsigned char otherStuff[120]; /* 0x3c words, or 0x7E bytes */ + unsigned short checkSum; /* when added to the sum of all words above, this should be 0xBABA */ unsigned char padding1[3968]; }; -// main and backup region in gbe +/* main and backup region in gbe */ struct GBEREGIONRECORD_8K { struct GBEREGIONRECORD_4K main; struct GBEREGIONRECORD_4K backup; - // Backup region: - // This is actually "main" on X200, since the real main has a bad checksum - // and other errors. You should do what you need on this one (if modifying - // lenovobios's gbe region) and then copy to main + /* + * Backup region: + * This is actually "main" on X200, since the real main has a bad checksum + * and other errors. You should do what you need on this one (if modifying + * lenovobios's gbe region) and then copy to main + */ }; -// --------------------------------------------------------------------- -// Gbe functions -// --------------------------------------------------------------------- +/* + * --------------------------------------------------------------------- + * Gbe functions: + * --------------------------------------------------------------------- + */ -// Read a 16-bit unsigned int from a supplied region buffer +/* 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 +/* + * 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. + 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) - if (isBackup) offset = 0x1000>>1; // this function uses *word* not *byte* indexes. + /* + * if isBackup is true, use 2nd gbe region ("backup" region) + * this function uses *word* not *byte* indexes, hence the bit shift. + */ + if (isBackup) offset = 0x1000>>1; for (i = 0; i < 0x3F; i++) { regionWord = gbeGetRegionWordFrom8kBuffer(i+offset, regionData); @@ -90,7 +109,7 @@ unsigned short gbeGetChecksumFrom8kBuffer(char* regionData, unsigned short desir return checksum; } -// checksum calculation for 4k gbe struct (algorithm based on datasheet) +/* checksum calculation for 4k gbe struct (algorithm based on datasheet) */ unsigned short gbeGetChecksumFrom4kStruct(struct GBEREGIONRECORD_4K gbeStruct4k, unsigned short desiredValue) { char gbeBuffer4k[GBEREGIONSIZE>>1]; @@ -98,12 +117,14 @@ unsigned short gbeGetChecksumFrom4kStruct(struct GBEREGIONRECORD_4K gbeStruct4k, return gbeGetChecksumFrom8kBuffer(gbeBuffer4k, desiredValue, 0); } -// modify the gbe region extracted from a factory.rom dump +/* 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 - // the descriptor so that the main region is usable. + /* + * 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); @@ -111,12 +132,14 @@ struct GBEREGIONRECORD_8K deblobbedGbeStructFromFactory(struct GBEREGIONRECORD_8 deblobbedGbeStruct8k.backup.checkSum = gbeGetChecksumFrom4kStruct(deblobbedGbeStruct8k.backup, 0xBABA); memcpy(&deblobbedGbeStruct8k.main, &deblobbedGbeStruct8k.backup, GBEREGIONSIZE>>1); - // 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 + /* + * 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); diff --git a/resources/utilities/ich9deblob/ich9deblob.c b/resources/utilities/ich9deblob/ich9deblob.c index 49d5a9b..94bc2c2 100644 --- a/resources/utilities/ich9deblob/ich9deblob.c +++ b/resources/utilities/ich9deblob/ich9deblob.c @@ -21,6 +21,8 @@ * along with this program. If not, see . */ +/* Initially based on proof of concept by Steve Shenton. */ + /* * Read a factory.rom dump (ich9m/gm45 machines) and * modify the flash descriptor to remove all regions except descriptor, @@ -31,72 +33,86 @@ * for use in libreboot. Currently tested: ThinkPad X200 (coreboot/libreboot) */ -// See docs/hcl/x200_remove_me.html for info plus links to datasheet (also linked below) - -// Info about flash descriptor (read page 850 onwards): -// * http://www.intel.co.uk/content/dam/doc/datasheet/io-controller-hub-9-datasheet.pdf - -// Info about Gbe region (read whole datasheet): -// * http://www.intel.co.uk/content/dam/doc/application-note/i-o-controller-hub-9m-82567lf-lm-v-nvm-map-appl-note.pdf -// * https://communities.intel.com/community/wired/blog/2010/10/14/how-to-basic-eeprom-checksums +/* + * See docs/hcl/x200_remove_me.html for info plus links to datasheet (also linked below) + * + * Info about flash descriptor (read page 850 onwards): + * http://www.intel.co.uk/content/dam/doc/datasheet/io-controller-hub-9-datasheet.pdf + * + * Info about Gbe region (read whole datasheet): + * http://www.intel.co.uk/content/dam/doc/application-note/i-o-controller-hub-9m-82567lf-lm-v-nvm-map-appl-note.pdf + * https://communities.intel.com/community/wired/blog/2010/10/14/how-to-basic-eeprom-checksums + */ #include #include -#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 "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. */ int main(int argc, char *argv[]) { - // descriptor region. Will have an actual descriptor struct mapped to it (from the factory.rom dump) - // and then it will be modified (deblobbed) to remove the ME/AMT + /* + * descriptor region. Will have an actual descriptor struct mapped to it (from the factory.rom dump) + * and then it will be modified (deblobbed) to remove the ME/AMT + */ char factoryDescriptorBuffer[DESCRIPTORREGIONSIZE]; struct DESCRIPTORREGIONRECORD factoryDescriptorStruct; char deblobbedDescriptorBuffer[DESCRIPTORREGIONSIZE]; struct DESCRIPTORREGIONRECORD deblobbedDescriptorStruct; - // gbe region. Well have actual gbe buffer mapped to it (from the factory.rom dump) - // and then it will be modified to correct the main region + /* + * gbe region. Well have actual gbe buffer mapped to it (from the factory.rom dump) + * and then it will be modified to correct the main region + */ char factoryGbeBuffer8k[GBEREGIONSIZE]; struct GBEREGIONRECORD_8K factoryGbeStruct8k; char deblobbedGbeBuffer8k[GBEREGIONSIZE]; struct GBEREGIONRECORD_8K deblobbedGbeStruct8k; - // Used to store the location of the Gbe - // region inside the factory.rom image. + /* + * Used to store the location of the Gbe + * region inside the factory.rom image. + */ unsigned int factoryGbeRegionStart; - // names of the files that this utility will handle - char* factoryRomFilename = "factory.rom"; // user-supplied factory.bin dump (original firmware) - char* deblobbedDescriptorFilename = "deblobbed_descriptor.bin"; // descriptor+gbe: to be dd'd to beginning of a libreboot image + /* names of the files that this utility will handle */ + char* factoryRomFilename = "factory.rom"; /* user-supplied factory.bin dump (original firmware) */ + char* deblobbedDescriptorFilename = "deblobbed_descriptor.bin"; /* descriptor+gbe: to be dd'd to beginning of a libreboot image */ - // Used when reading the factory.rom to extract descriptor/gbe regions + /* Used when reading the factory.rom to extract descriptor/gbe regions */ unsigned int bufferLength; - // For storing the size of the factory.rom dump in bytes + /* For storing the size of the factory.rom dump in bytes */ unsigned int factoryRomSize; - // ----------------------------------------------------------------------------------------------- - - // Compatibility checks. This version of ich9deblob is not yet porable. + /* + * ------------------------------------------------------------------ + * Compatibility checks. This version of ich9deblob is not yet portable. + * ------------------------------------------------------------------ + */ + if (systemOrCompilerIncompatible(factoryDescriptorStruct, factoryGbeStruct8k)) return 1; + /* If true, fail with error message */ - // ----------------------------------------------------------------------------------------------- - - // Open factory.rom, needed for extracting descriptor and gbe - // ----------------------------------------------- + /* + * ------------------------------------------------------------------ + * Extract the descriptor and gbe regions from the factory.rom dump + * ------------------------------------------------------------------ + */ FILE* fileStream = NULL; - fileStream = fopen(factoryRomFilename, "rb"); // open factory.rom + fileStream = fopen(factoryRomFilename, "rb"); /* open factory.rom */ if (NULL == fileStream) { printf("\nerror: could not open factory.rom\n"); return 1; } printf("\nfactory.rom opened successfully\n"); - // ----------------------------------------------- - // Get the descriptor region dump from the factory.rom - // (goes in factoryDescriptorBuffer variable) + /* + * Get the descriptor region dump from the factory.rom + * (goes in factoryDescriptorBuffer variable) + */ bufferLength = fread(factoryDescriptorBuffer, sizeof(char), DESCRIPTORREGIONSIZE, fileStream); if (DESCRIPTORREGIONSIZE != bufferLength) // { @@ -104,30 +120,38 @@ int main(int argc, char *argv[]) return 1; } printf("\ndescriptor region read successfully\n"); - // copy descriptor buffer into descriptor struct memory - // factoryDescriptorStruct is an instance of a struct that actually - // defines the locations of all these variables in the descriptor, - // as defined in the datasheets. This allows us to map the extracted - // descriptor over the struct so that it can then be modified - // for libreboot's purpose + /* + * copy descriptor buffer into descriptor struct memory + * factoryDescriptorStruct is an instance of a struct that actually + * defines the locations of all these variables in the descriptor, + * as defined in the datasheets. This allows us to map the extracted + * descriptor over the struct so that it can then be modified + * for libreboot's purpose + */ memcpy(&factoryDescriptorStruct, &factoryDescriptorBuffer, DESCRIPTORREGIONSIZE); - // ^ the above is just for reference if needed. The modifications will be made here: + /* + * ^ the above is just for reference if needed. The modifications will be made here: + */ memcpy(&deblobbedDescriptorStruct, &factoryDescriptorBuffer, DESCRIPTORREGIONSIZE); - // ----------------------------------------------------------------------------------------------- - - // Get the gbe region dump from the factory.rom - - // get original GBe region location - // (it will be moved to the beginning of the flash, after the descriptor region) - // note for example, factoryGbeRegionStart is set to < #include -#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 "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 */ -// --------------------------------------------------------------------- -// x86 compatibility checking: -// --------------------------------------------------------------------- +/* + * --------------------------------------------------------------------- + * x86 compatibility checking: + * --------------------------------------------------------------------- + */ -// Basically, this should only return true on non-x86 machines -int structSizesIncorrect(struct DESCRIPTORREGIONRECORD descriptorDummy, struct GBEREGIONRECORD_8K gbe8kDummy) { +/* fail if struct size is incorrect */ +int structSizesIncorrect(struct DESCRIPTORREGIONRECORD descriptorDummy, struct GBEREGIONRECORD_8K gbe8kDummy) +{ unsigned int descriptorRegionStructSize = sizeof(descriptorDummy); unsigned int gbeRegion8kStructSize = sizeof(gbe8kDummy); - // check compiler bit-packs in a compatible way. basically, it is expected that this code will be used on x86 + + /* check compiler bit-packs in a compatible way. basically, it is expected that this code will be used on x86 */ if (DESCRIPTORREGIONSIZE != descriptorRegionStructSize){ printf("\nerror: compiler incompatibility: descriptor struct length is %i bytes (should be %i)\n", descriptorRegionStructSize, DESCRIPTORREGIONSIZE); return 1; @@ -44,47 +48,52 @@ int structSizesIncorrect(struct DESCRIPTORREGIONRECORD descriptorDummy, struct G printf("\nerror: compiler incompatibility: gbe struct length is %i bytes (should be %i)\n", gbeRegion8kStructSize, GBEREGIONSIZE); return 1; } + return 0; } -int systemIsBigEndian() { - // endianness check. big endian forced to fail +/* endianness check. big endian forced to fail */ +int systemIsBigEndian() +{ unsigned short steak = 0xBEEF; unsigned char *grill = (unsigned char*)&steak; + if (*grill==0xBE) { printf("\nunsigned short 0xBEEF: first byte should be EF, but it's BE. Your system is big endian, and unsupported (only little endian is tested)\n"); return 1; } - return 0; + return 0; /* you got the good half of the steak */ } -// fail if members are presented in the wrong order +/* fail if members are presented in the wrong order */ int structMembersWrongOrder() { int i; struct DESCRIPTORREGIONRECORD descriptorDummy; unsigned char *meVsccTablePtr = (unsigned char*)&descriptorDummy.meVsccTable; - // These do not use bitfields. - descriptorDummy.meVsccTable.jid0 = 0x01020304; // unsigned int 32-bit - descriptorDummy.meVsccTable.vscc0 = 0x10203040; // unsigned int 32-bit - descriptorDummy.meVsccTable.jid1 = 0x11223344; // unsigned int 32-bit - descriptorDummy.meVsccTable.vscc1 = 0x05060708; // unsigned int 32-bit - descriptorDummy.meVsccTable.jid2 = 0x50607080; // unsigned int 32-bit - descriptorDummy.meVsccTable.vscc2 = 0x55667788; // unsigned int 32-bit - descriptorDummy.meVsccTable.padding[0] = 0xAA; // unsigned char 8-bit - descriptorDummy.meVsccTable.padding[1] = 0xBB; // unsigned char 8-bit - descriptorDummy.meVsccTable.padding[2] = 0xCC; // unsigned char 8-bit - descriptorDummy.meVsccTable.padding[3] = 0xDD; // unsigned char 8-bit - - // Look from the top down, and concatenate the unsigned ints but - // with each unsigned in little endian order. - // Then, concatenate the unsigned chars in big endian order. (in the padding array) + /* These do not use bitfields. */ + descriptorDummy.meVsccTable.jid0 = 0x01020304; /* unsigned int 32-bit */ + descriptorDummy.meVsccTable.vscc0 = 0x10203040; /* unsigned int 32-bit */ + descriptorDummy.meVsccTable.jid1 = 0x11223344; /* unsigned int 32-bit */ + descriptorDummy.meVsccTable.vscc1 = 0x05060708; /* unsigned int 32-bit */ + descriptorDummy.meVsccTable.jid2 = 0x50607080; /* unsigned int 32-bit */ + descriptorDummy.meVsccTable.vscc2 = 0x55667788; /* unsigned int 32-bit */ + descriptorDummy.meVsccTable.padding[0] = 0xAA; /* unsigned char 8-bit */ + descriptorDummy.meVsccTable.padding[1] = 0xBB; /* unsigned char 8-bit */ + descriptorDummy.meVsccTable.padding[2] = 0xCC; /* unsigned char 8-bit */ + descriptorDummy.meVsccTable.padding[3] = 0xDD; /* unsigned char 8-bit */ - // combined, these should become: - // 01020304 10203040 11223344 05060708 50607080 55667788 AA BB CC DD (ignore this. big endian. just working it out manually:) - // 04030201 40302010 44332211 08070605 80706050 88776655 AA BB CC DD (ignore this. not byte-separated, just working it out:) - // 04 03 02 01 40 30 20 10 44 33 22 11 08 07 06 05 80 70 60 50 88 77 66 55 AA BB CC DD <-- it should match this + /* + * Look from the top down, and concatenate the unsigned ints but + * with each unsigned in little endian order. + * Then, concatenate the unsigned chars in big endian order. (in the padding array) + * + * combined, these should become: + * 01020304 10203040 11223344 05060708 50607080 55667788 AA BB CC DD (ignore this. big endian. just working it out manually:) + * 04030201 40302010 44332211 08070605 80706050 88776655 AA BB CC DD (ignore this. not byte-separated, just working it out:) + * 04 03 02 01 40 30 20 10 44 33 22 11 08 07 06 05 80 70 60 50 88 77 66 55 AA BB CC DD <-- it should match this + */ printf("\nStruct member order check (descriptorDummy.meVsccTable) with junk/dummy data:"); printf("\nShould be: 04 03 02 01 40 30 20 10 44 33 22 11 08 07 06 05 80 70 60 50 88 77 66 55 aa bb cc dd "); @@ -110,31 +119,34 @@ int structMembersWrongOrder() printf("Incorrect order.\n"); return 1; } + printf("Correct order.\n"); return 0; } -// fail if bit fields are presented in the wrong order +/* fail if bit fields are presented in the wrong order */ int structBitfieldWrongOrder() { int i; struct DESCRIPTORREGIONRECORD descriptorDummy; unsigned char *flMap0Ptr = (unsigned char*)&descriptorDummy.flMaps.flMap0; - descriptorDummy.flMaps.flMap0.FCBA = 0xA2; // :8 --> 10100010 - descriptorDummy.flMaps.flMap0.NC = 0x02; // :2 --> 10 - descriptorDummy.flMaps.flMap0.reserved1 = 0x38; // :6 --> 111000 - descriptorDummy.flMaps.flMap0.FRBA = 0xD2; // :8 --> 11010010 - descriptorDummy.flMaps.flMap0.NR = 0x05; // :3 --> 101 - descriptorDummy.flMaps.flMap0.reserved2 = 0x1C; // :5 --> 11100 - - // Look from the top bottom up, and concatenate the binary strings. - // Then, convert the 8-bit groups to hex and reverse the (8-bit)byte order + descriptorDummy.flMaps.flMap0.FCBA = 0xA2; /* :8 --> 10100010 */ + descriptorDummy.flMaps.flMap0.NC = 0x02; /* :2 --> 10 */ + descriptorDummy.flMaps.flMap0.reserved1 = 0x38; /* :6 --> 111000 */ + descriptorDummy.flMaps.flMap0.FRBA = 0xD2; /* :8 --> 11010010 */ + descriptorDummy.flMaps.flMap0.NR = 0x05; /* :3 --> 101 */ + descriptorDummy.flMaps.flMap0.reserved2 = 0x1C; /* :5 --> 11100 */ - // combined, these should become (in memory), in binary: - // 10100010 11100010 11010010 11100101 - // or in hex: - // A2 E2 D2 E5 + /* + * Look from the top bottom up, and concatenate the binary strings. + * Then, convert the 8-bit groups to hex and reverse the (8-bit)byte order + * + * combined, these should become (in memory), in binary: + * 10100010 11100010 11010010 11100101 + * or in hex: + * A2 E2 D2 E5 + */ printf("\nBitfield order check (descriptorDummy.flMaps.flMaps0) with junk/dummy data:"); printf("\nShould be: a2 e2 d2 e5 "); @@ -149,11 +161,12 @@ int structBitfieldWrongOrder() printf("Incorrect order.\n"); return 1; } + printf("Correct order.\n"); return 0; } -// Compatibility checks. This version of ich9deblob is not yet porable. +/* Compatibility checks. This version of ich9deblob is not yet porable. */ int systemOrCompilerIncompatible(struct DESCRIPTORREGIONRECORD descriptorStruct, struct GBEREGIONRECORD_8K gbeStruct8k) { if (structSizesIncorrect(descriptorStruct, gbeStruct8k)) return 1; -- cgit v0.9.1