summaryrefslogtreecommitdiffstats
path: root/resources/utilities/ich9deblob/x86compatibility.c
blob: 985cedfc1e077c30101af9dac6bfecaab948f9ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <stdio.h>
#include <string.h>

#include "ich9desc.h" // structs describing what's in the descriptor region
#include "gbe/struct.h" // structs describing what's in the gbe region

// ---------------------------------------------------------------------
// x86 compatibility checking:
// ---------------------------------------------------------------------

// Basically, this should only return true on non-x86 machines
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
	if (DESCRIPTORREGIONSIZE != descriptorRegionStructSize){
		printf("\nerror: compiler incompatibility: descriptor struct length is %i bytes (should be %i)\n", descriptorRegionStructSize, DESCRIPTORREGIONSIZE);
		return 1;
	}
	if (GBEREGIONSIZE != gbeRegion8kStructSize){
		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
	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;
}

// 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)
	
	// 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 ");
	printf("\nAnd it is: ");
	
	for (i = 0; i < 28; i++) {
		printf("%02x ", *(meVsccTablePtr + i));	
	}
	printf("\n");
	
	if (
			!
			(
				*meVsccTablePtr      == 0x04 && *(meVsccTablePtr+1)  == 0x03 && *(meVsccTablePtr+2)  == 0x02 && *(meVsccTablePtr+3)  == 0x01
			&& *(meVsccTablePtr+4)  == 0x40 && *(meVsccTablePtr+5)  == 0x30 && *(meVsccTablePtr+6)  == 0x20 && *(meVsccTablePtr+7)  == 0x10
			&& *(meVsccTablePtr+8)  == 0x44 && *(meVsccTablePtr+9)  == 0x33 && *(meVsccTablePtr+10) == 0x22 && *(meVsccTablePtr+11) == 0x11
			&& *(meVsccTablePtr+12) == 0x08 && *(meVsccTablePtr+13) == 0x07 && *(meVsccTablePtr+14) == 0x06 && *(meVsccTablePtr+15) == 0x05
			&& *(meVsccTablePtr+16) == 0x80 && *(meVsccTablePtr+17) == 0x70 && *(meVsccTablePtr+18) == 0x60 && *(meVsccTablePtr+19) == 0x50
			&& *(meVsccTablePtr+20) == 0x88 && *(meVsccTablePtr+21) == 0x77 && *(meVsccTablePtr+22) == 0x66 && *(meVsccTablePtr+23) == 0x55
			&& *(meVsccTablePtr+24) == 0xAA && *(meVsccTablePtr+25) == 0xBB && *(meVsccTablePtr+26) == 0xCC && *(meVsccTablePtr+27) == 0xDD
	      )
	   ) {
		printf("Incorrect order.\n");
		return 1;
	}
	printf("Correct order.\n");
	return 0;
}

// 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
	
	// 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 ");
	printf("\nAnd it is: ");

	for (i = 0; i < 4; i++) {
		printf("%02x ", *(flMap0Ptr + i));	
	}
	printf("\n");
	
	if (!(*flMap0Ptr == 0xA2 && *(flMap0Ptr+1) == 0xE2 && *(flMap0Ptr+2) == 0xD2 && *(flMap0Ptr+3) == 0xE5)) {
		printf("Incorrect order.\n");
		return 1;
	}
	printf("Correct order.\n");
	return 0;
}

// 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;
	if (systemIsBigEndian()) return 1;
	if (structBitfieldWrongOrder()) return 1;
	if (structMembersWrongOrder()) return 1; 
	return 0;
}