Chameleon

Chameleon Commit Details

Date:2014-01-09 13:10:23 (10 years 2 months ago)
Author:ErmaC
Commit:2327
Parents: 2326
Message:General update (typo, indent, brackets)
Changes:
M/trunk/i386/libsaio/cache.c
M/trunk/i386/libsaio/gma.c
M/trunk/i386/boot2/boot.c
M/trunk/i386/boot2/boot2.s
M/trunk/i386/libsaio/dram_controllers.c
M/trunk/i386/libsaio/ntfs.c
M/trunk/i386/libsa/printf.c
M/trunk/i386/boot2/boot.h
M/trunk/i386/boot2/modules.c
M/trunk/i386/libsaio/pci.c
M/trunk/i386/libsaio/bootstruct.h
M/trunk/i386/libsa/string.c
M/trunk/i386/libsaio/aml_generator.c
M/trunk/i386/libsaio/pci.h
M/trunk/i386/libsaio/acpi_patcher.c
M/trunk/i386/libsaio/aml_generator.h
M/trunk/i386/libsaio/allocate.c
M/trunk/i386/libsaio/platform.c
M/trunk/i386/libsaio/msdos.c
M/trunk/i386/libsaio/bootargs.h
M/trunk/i386/boot2/gui.c
M/trunk/i386/libsaio/platform.h
M/trunk/i386/libsaio/disk.c
M/trunk/i386/libsaio/device_inject.c
M/trunk/i386/libsaio/hda.c
M/trunk/i386/libsaio/saio_internal.h
M/trunk/i386/boot2/ramdisk.c
M/trunk/i386/boot2/options.c
M/trunk/i386/libsaio/xml.c
M/trunk/i386/libsaio/asm.s
M/trunk/i386/libsaio/device_inject.h
M/trunk/i386/libsaio/bios.h
M/trunk/i386/config/confdata.c
M/trunk/i386/boot2/picopng.c
M/trunk/i386/libsaio/console.c
M/trunk/i386/boot2/graphics.c
M/trunk/i386/libsaio/xml.h
M/trunk/i386/libsaio/fdisk.h
M/trunk/i386/libsaio/base64-decode.c
M/trunk/i386/libsaio/efi.h
M/trunk/i386/libsaio/device_tree.c
M/trunk/i386/libsaio/pci_root.c
M/trunk/i386/libsaio/befs.c
M/trunk/i386/libsaio/biosfn.c
M/trunk/i386/libsaio/hfs.c
M/trunk/i386/boot2/drivers.c
M/trunk/i386/libsaio/device_tree.h
M/trunk/i386/libsaio/memvendors.h
M/trunk/i386/libsaio/saio_types.h
M/trunk/i386/libsaio/spd.c
M/trunk/i386/libsaio/cpu.c
M/trunk/i386/config/symbol.c
M/trunk/i386/libsaio/spd.h

File differences

trunk/i386/libsaio/xml.c
6868
6969
7070
71
72
73
74
75
76
71
72
73
74
75
76
7777
7878
7979
8080
81
82
83
84
81
82
83
84
8585
8686
8787
......
8989
9090
9191
92
93
94
95
96
97
98
99
92
93
94
95
96
97
98
99
100100
101101
102102
103103
104
105
104
105
106106
107107
108108
......
114114
115115
116116
117
117118
118119
119120
......
127128
128129
129130
130
131
131132
132133
133134
......
140141
141142
142143
143
144
145
146
147
148
144
145
146
147
148
149
150
151
152
153
149154
150155
151156
......
154159
155160
156161
157
162
158163
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
174187
175188
176189
177190
178
179
180
181
191
192
193
194
195
182196
183197
184198
......
190204
191205
192206
193
207
208
209
210
194211
195
196
197
212
213
214
198215
199
216
200217
201218
202219
203
220
221
222
204223
205224
206225
207226
208
227
209228
210229
211230
212231
213232
214233
215
216
234
235
236
237
217238
218239
219240
......
230251
231252
232253
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
254
255
256
257
258
282259
283
284
260
261
262
263
264
265
266
285267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
286306
287307
288308
......
294314
295315
296316
297
298
299
317
318
319
300320
301
302
303
304
305
306321
322
323
324
325
326
307327
308328
309329
310330
311331
312332
313
333
314334
315
335
316336
317337
318338
......
335355
336356
337357
338
358
339359
340
341
360
361
362
363
342364
343365
344366
345367
368
369
346370
347371
348372
......
362386
363387
364388
365
389
366390
367391
368392
......
431455
432456
433457
434
458
435459
436460
437461
......
518542
519543
520544
521
545
522546
523547
524548
525549
526550
527
551
528552
529553
530554
......
535559
536560
537561
538
562
539563
540564
541565
......
549573
550574
551575
552
576
553577
554578
555579
580
556581
557582
558583
559
560
561
584
585
586
587
588
562589
563590
564591
......
571598
572599
573600
574
575
601
602
576603
577
578
579
580
581
582
604
605
606
607
608
609
610
611
583612
584
613
585614
586
587
588
589
590
591
592
593
594
595
596
615
616
617
618
619
620
621
622
623
624
625
626
627
628
597629
598
599
600
601
602
603
630
631
632
633
634
635
604636
605
606
637
638
607639
608
609
610
611
612
613
640
641
642
643
644
645
614646
615647
616648
......
619651
620652
621653
622
623
624
654
655
656
625657
626
627
658
659
660
661
628662
629
630
663
664
665
666
667
668
669
670
671
672
631673
632
633
634
635
636
637
674
675
676
677
678
679
638680
639
640
641
642
643
644
645
646
647
648
649
681
682
683
650684
651
685
652686
653
687
654688
655
689
656690
657691
658692
......
661695
662696
663697
664
665
698
699
666700
667
668
701
702
703
704
669705
670706
671
707
708
709
672710
673
674
675
676
677
678
711
712
713
714
715
679716
680
681
682
717
718
719
683720
684
685
686
687
721
722
723
724
688725
689726
690727
......
693730
694731
695732
696
733
697734
698
735
699736
700
737
701738
702739
703740
......
715752
716753
717754
718
719
720
721
722
723
724
755
756
725757
758
759
760
761
762
726763
727764
728765
......
744781
745782
746783
747
784
748785
749786
750787
......
776813
777814
778815
779
780
816
817
781818
782819
783820
784
785
786
787
788
821
822
823
824
825
789826
790827
791828
......
794831
795832
796833
797
798
799
834
835
836
800837
801
802
803
804
805
806
838
839
840
841
842
843
807844
808845
809846
810847
811848
812
813
814
849
850
851
815852
816
817
818
819
820
853
854
855
856
857
821858
822859
823860
......
826863
827864
828865
829
830
831
832
833
834
835
836
837
866
867
868
869
870
871
872
873
874
838875
839876
840
841
842
843
877
878
879
880
844881
845
846
847
848
849
882
883
884
885
886
850887
851888
852889
......
855892
856893
857894
858
859
860
861
862
863
864
865
895
896
897
898
899
900
901
902
866903
867
868
869
870
871
904
905
906
907
908
872909
873910
874911
......
877914
878915
879916
880
917
881918
882
883
884
885
886
887
888
889
890
891
892
919
893920
894
895
896
897
898
899
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
900936
901937
902938
......
9701006
9711007
9721008
973
1009
1010
1011
1012
9741013
975
1014
1015
1016
1017
1018
1019
1020
9761021
977
978
979
980
981
982
983
1022
1023
1024
1025
9841026
985
986
1027
1028
9871029
988
1030
9891031
9901032
9911033
......
9941036
9951037
9961038
997
998
999
1039
1040
1041
10001042
10011043
10021044
......
10101052
10111053
10121054
1013
1055
10141056
1015
1016
1017
1018
1057
1058
1059
1060
10191061
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1062
1063
1064
1065
1066
1067
1068
10371069
1038
1039
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
10401088
10411089
10421090
......
10461094
10471095
10481096
1049
1097
10501098
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
10671127
10681128
10691129
......
10731133
10741134
10751135
1076
1136
10771137
1078
1079
1138
1139
10801140
1081
1082
1141
1142
1143
1144
1145
1146
10831147
1084
1085
1086
1148
1149
1150
10871151
1088
1089
1090
1152
1153
1154
1155
1156
1157
10911158
10921159
10931160
10941161
1095
1162
1163
1164
1165
10961166
10971167
10981168
10991169
11001170
11011171
1102
1172
11031173
11041174
11051175
11061176
1107
1108
1109
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
11101190
11111191
11121192
......
11161196
11171197
11181198
1119
1199
11201200
11211201
11221202
11231203
1124
1125
1126
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
11271217
11281218
11291219
11301220
1131
1132
1133
1221
11341222
11351223
11361224
11371225
1138
1226
1227
1228
1229
11391230
1140
1141
1142
1231
1232
1233
1234
1235
11431236
11441237
11451238
11461239
11471240
1148
1149
1150
1151
1152
1153
1154
1155
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
11561251
11571252
11581253
......
11601255
11611256
11621257
1163
1164
1165
1258
11661259
11671260
11681261
......
11741267
11751268
11761269
1177
1178
1179
1270
11801271
11811272
11821273
11831274
1184
1185
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
11861285
11871286
11881287
......
11981297
11991298
12001299
1201
1300
1301
1302
1303
1304
12021305
12031306
12041307
12051308
12061309
1207
1310
1311
1312
1313
12081314
1209
1210
1315
1316
12111317
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
12281334
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1335
12441336
1245
1246
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
12471353
}
struct Module {
struct Module *nextModule;
long willLoad;
TagPtr dict;
char *plistAddr;
long plistLength;
char *driverPath;
struct Module *nextModule;
longwillLoad;
TagPtrdict;
char*plistAddr;
longplistLength;
char*driverPath;
};
typedef struct Module Module, *ModulePtr;
struct DriverInfo {
char *plistAddr;
long plistLength;
void *moduleAddr;
long moduleLength;
char*plistAddr;
longplistLength;
void*moduleAddr;
longmoduleLength;
};
typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
#define kDriverPackageSignature2 'MOSX'
struct DriversPackage {
unsigned long signature1;
unsigned long signature2;
unsigned long length;
unsigned long adler32;
unsigned long version;
unsigned long numDrivers;
unsigned long reserved1;
unsigned long reserved2;
unsigned long signature1;
unsigned long signature2;
unsigned long length;
unsigned long adler32;
unsigned long version;
unsigned long numDrivers;
unsigned long reserved1;
unsigned long reserved2;
};
typedef struct DriversPackage DriversPackage;
enum {
kCFBundleType2,
kCFBundleType3
kCFBundleType2,
kCFBundleType3
};
static long ParseTagInteger(char *buffer, TagPtr *tag);
static long ParseTagData(char *buffer, TagPtr *tag);
static long ParseTagDate(char *buffer, TagPtr *tag);
//static long ParseTagBoolean(char *buffer, TagPtr *tag, long type);
static long GetNextTag(char *buffer, char **tag, long *start);
static long FixDataMatchingTag(char *buffer, char *tag);
static TagPtr NewTag(void);
// XMLGetProperty
TagPtr
XMLGetProperty( TagPtr dict, const char * key )
XMLGetProperty(TagPtr dict, const char * key)
{
TagPtr tagList, tag;
tag = tagList;
tagList = tag->tagNext;
if ((tag->type != kTagTypeKey) || (tag->string == 0)) continue;
if (!strcmp(tag->string, key)) return tag->tag;
}
return 0;
if ((tag->type != kTagTypeKey) || (tag->string == 0)) {
continue;
}
if (!strcmp(tag->string, key)) {
return tag->tag;
}
}
return 0;
}
//==========================================================================
TagPtr
XMLGetKey( TagPtr dict, int id )
{
TagPtr tagList, tag;
TagPtr tagList, tag;
if (dict->type != kTagTypeDict) return 0;
tag = 0;
int element = 0;
tagList = dict->tag;
while (tagList && element != id)
{
tag = tagList;
tagList = tag->tagNext;
if ((tag->type != kTagTypeKey) || (tag->string == 0)) continue;
element++;
if(id == element) return tag;
}
return 0;
if (dict->type != kTagTypeDict) {
return 0;
}
tag = 0;
int element = 0;
tagList = dict->tag;
while (tagList && element != id)
{
tag = tagList;
tagList = tag->tagNext;
if ((tag->type != kTagTypeKey) || (tag->string == 0)) {
continue;
}
element++;
if(id == element) {
return tag;
}
}
return 0;
}
TagPtr XMLGetValueForKey(TagPtr key)
{
if (!key ||
key->type != kTagTypeKey) return 0;
return key->tag;
if (!key || key->type != kTagTypeKey) {
return 0;
}
return key->tag;
}
int count = 0;
TagPtr tagList, tag;
if (dict->type != kTagTypeDict && dict->type != kTagTypeArray) return 0;
if (dict->type != kTagTypeDict && dict->type != kTagTypeArray) {
return 0;
}
tag = 0;
tagList = dict->tag;
while (tagList)
{
tagList = dict->tag;
while (tagList)
{
tag = tagList;
tagList = tag->tagNext;
tagList = tag->tagNext;
if (((tag->type != kTagTypeKey) && ((tag->string == 0) || (tag->string[0] == 0)))
&& (dict->type != kTagTypeArray)// If we are an array, any element is valid
) continue;
) {
continue;
}
//if(tag->type == kTagTypeKey) printf("Located key %s\n", tag->string);
count++;
}
}
return count;
}
TagPtr XMLGetElement( TagPtr dict, int id )
{
if(dict->type != kTagTypeArray) return 0;
if(dict->type != kTagTypeArray) {
return 0;
}
int element = 0;
TagPtr tmp = dict->tag;
char*
XMLDecode(const char* src)
{
typedef const struct XMLEntity {
const char* name;
size_t nameLen;
char value;
} XMLEntity;
/* This is ugly, but better than specifying the lengths by hand */
#define _e(str,c) {str,sizeof(str)-1,c}
const XMLEntity ents[] = {
_e("quot;",'"'), _e("apos;",'\''),
_e("lt;", '<'), _e("gt;", '>'),
_e("amp;", '&')
};
size_t len;
const char *s;
char *out, *o;
if ( !src || !(len = strlen(src)) || !(out = malloc(len+1)) )
return 0;
o = out;
s = src;
while (s <= src+len) /* Make sure the terminator is also copied */
{
if ( *s == '&' )
{
bool entFound = false;
int i;
s++;
for ( i = 0; i < sizeof(ents)/sizeof(ents[0]); i++)
{
if ( strncmp(s, ents[i].name, ents[i].nameLen) == 0 )
{
entFound = true;
break;
}
}
if ( entFound )
{
*o++ = ents[i].value;
s += ents[i].nameLen;
continue;
}
}
*o++ = *s++;
}
typedef const struct XMLEntity {
const char* name;
size_t nameLen;
char value;
} XMLEntity;
return out;
}
/* This is ugly, but better than specifying the lengths by hand */
#define _e(str,c) {str,sizeof(str)-1,c}
const XMLEntity ents[] = {
_e("quot;",'"'), _e("apos;",'\''),
_e("lt;", '<'), _e("gt;", '>'),
_e("amp;", '&')
};
size_t len;
const char *s;
char *out, *o;
if ( !src || !(len = strlen(src)) || !(out = malloc(len+1)) ) {
return 0;
}
o = out;
s = src;
while (s <= src+len) /* Make sure the terminator is also copied */
{
if ( *s == '&' ) {
bool entFound = false;
int i;
s++;
for ( i = 0; i < sizeof(ents)/sizeof(ents[0]); i++)
{
if ( strncmp(s, ents[i].name, ents[i].nameLen) == 0 ) {
entFound = true;
break;
}
}
if ( entFound ) {
*o++ = ents[i].value;
s += ents[i].nameLen;
continue;
}
}
*o++ = *s++;
}
return out;
}
//#if UNUSED
//==========================================================================
// XMLParseFile
long
XMLParseFile( char * buffer, TagPtr * dict )
{
long length, pos;
TagPtr tag;
pos = 0;
long length, pos;
TagPtr tag;
pos = 0;
char *configBuffer;
int strlength = strlen(buffer);
configBuffer = malloc(strlength+1);
bcopy(buffer, configBuffer, strlength);
configBuffer[strlength] = 0;
int strlength = strlen(buffer);
configBuffer = malloc(strlength+1);
bcopy(buffer, configBuffer, strlength);
configBuffer[strlength] = 0;
buffer_start = configBuffer;
while (1)
{
length = XMLParseNextTag(configBuffer + pos, &tag);
if (length == -1) break;
pos += length;
if (tag == 0) continue;
if (tag->type == kTagTypeDict) break;
{
long length, pos;
char * tagName;
length = GetNextTag(buffer, &tagName, 0);
if (length == -1) return -1;
if (length == -1) {
return -1;
}
pos = length;
if (!strncmp(tagName, kXMLTagPList, 6))
{
length = 0;
// just a header; nothing to parse
// return-via-reference tag should be left alone
}
/***** dict ****/
else if (!strcmp(tagName, kXMLTagDict))
{
length = ParseTagKey(buffer + pos, tag);
}
/***** string ****/
else if (!strcmp(tagName, kXMLTagString))
{
//printf("Located IDREF, id = %d, string = %s\n", id, str);
}
}
/***** integer ****/
else if (!strcmp(tagName, kXMLTagInteger))
{
{
length = ParseTagDate(buffer + pos, tag);
}
/***** date ****/
else if (!strncmp(tagName, kXMLTagDate " ", strlen(kXMLTagDate " ")))
{
length = ParseTagDate(buffer + pos, tag);
}
/***** false ****/
else if (!strcmp(tagName, kXMLTagFalse))
{
{
length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue);
}
/***** array ****/
else if (!strcmp(tagName, kXMLTagArray))
{
{
length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1);
}
/***** unknown ****/
else
{
// it wasn't parsed so we consumed no additional characters
*tag = 0;
length = 0;
}
if (length == -1) return -1;
if (length == -1) {
return -1;
}
return pos + length;
}
long length, pos;
TagPtr tagList, tmpTag;
tagList = 0;
pos = 0;
tagList = 0;
pos = 0;
if (!empty)
{
while (1)
{
length = XMLParseNextTag(buffer + pos, &tmpTag);
if (length == -1) break;
if (!empty)
{
while (1)
{
length = XMLParseNextTag(buffer + pos, &tmpTag);
if (length == -1) {
break;
}
pos += length;
pos += length;
if (tmpTag == 0) break;
tmpTag->tagNext = tagList;
tagList = tmpTag;
}
if (length == -1)
{
XMLFreeTag(tagList);
return -1;
}
}
// detect end of list
if (tmpTag == 0) {
break;
}
tmpTag->tagNext = tagList;
tagList = tmpTag;
}
if (length == -1)
{
XMLFreeTag(tagList);
return -1;
}
}
tmpTag = NewTag();
if (tmpTag == 0)
{
XMLFreeTag(tagList);
return -1;
}
tmpTag = NewTag();
if (tmpTag == 0)
{
XMLFreeTag(tagList);
return -1;
}
tmpTag->type = type;
tmpTag->string = 0;
tmpTag->type = type;
tmpTag->string = 0;
tmpTag->offset = buffer_start ? buffer - buffer_start : 0;
tmpTag->tag = tagList;
tmpTag->tagNext = 0;
*tag = tmpTag;
return pos;
tmpTag->tag = tagList;
tmpTag->tagNext = 0;
*tag = tmpTag;
return pos;
}
//==========================================================================
static long
ParseTagKey( char * buffer, TagPtr * tag )
{
long length, length2;
char *string;
TagPtr tmpTag, subTag;
long length, length2;
char *string;
TagPtr tmpTag, subTag;
length = FixDataMatchingTag(buffer, kXMLTagKey);
if (length == -1) return -1;
length = FixDataMatchingTag(buffer, kXMLTagKey);
if (length == -1) {
return -1;
}
length2 = XMLParseNextTag(buffer + length, &subTag);
if (length2 == -1) return -1;
length2 = XMLParseNextTag(buffer + length, &subTag);
if (length2 == -1) {
return -1;
}
tmpTag = NewTag();
if (tmpTag == 0) {
XMLFreeTag(subTag);
return -1;
}
tmpTag = NewTag();
if (tmpTag == 0)
{
XMLFreeTag(subTag);
return -1;
}
string = NewSymbol(buffer);
if (string == 0) {
XMLFreeTag(subTag);
XMLFreeTag(tmpTag);
return -1;
}
string = NewSymbol(buffer);
if (string == 0)
{
XMLFreeTag(subTag);
XMLFreeTag(tmpTag);
return -1;
}
tmpTag->type = kTagTypeKey;
tmpTag->string = string;
tmpTag->tag = subTag;
tmpTag->type = kTagTypeKey;
tmpTag->string = string;
tmpTag->tag = subTag;
tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
tmpTag->tagNext = 0;
tmpTag->tagNext = 0;
*tag = tmpTag;
*tag = tmpTag;
return length + length2;
return length + length2;
}
//==========================================================================
static long
ParseTagString( char * buffer, TagPtr * tag )
{
long length;
char * string;
long length;
char * string;
length = FixDataMatchingTag(buffer, kXMLTagString);
if (length == -1) return -1;
length = FixDataMatchingTag(buffer, kXMLTagString);
if (length == -1) {
return -1;
}
TagPtr tmpTag = NewTag();
if (tmpTag == 0) return -1;
if (tmpTag == 0) {
return -1;
}
string = NewSymbol(buffer);
if (string == 0)
{
XMLFreeTag(tmpTag);
return -1;
}
string = NewSymbol(buffer);
if (string == 0) {
XMLFreeTag(tmpTag);
return -1;
}
tmpTag->type = kTagTypeString;
tmpTag->string = string;
tmpTag->tag = 0;
tmpTag->type = kTagTypeString;
tmpTag->string = string;
tmpTag->tag = 0;
tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
tmpTag->tagNext = 0;
*tag = tmpTag;
return length;
tmpTag->tagNext = 0;
*tag = tmpTag;
return length;
}
//==========================================================================
static long
ParseTagInteger( char * buffer, TagPtr * tag )
{
long length, integer;
long length, integer;
bool negative = false;
TagPtr tmpTag;
TagPtr tmpTag;
char* val = buffer;
int size;
int size;
if(buffer[0] == '<')
{
return 0;
}
size = length = FixDataMatchingTag(buffer, kXMLTagInteger);
if (length == -1) return -1;
tmpTag = NewTag();
if (tmpTag == 0) return -1;
integer = 0;
size = length = FixDataMatchingTag(buffer, kXMLTagInteger);
if (length == -1) return -1;
tmpTag = NewTag();
if (tmpTag == 0) return -1;
integer = 0;
if(size > 1 && (val[1] == 'x' || val[1] == 'X'))// Hex value
{
val += 2;
{
printf("ParseTagInteger hex error (0x%x) in buffer %s\n", *val, buffer);
getchar();
XMLFreeTag(tmpTag);
XMLFreeTag(tmpTag);
return -1;
}
}
if (negative)
integer = -integer;
}
tmpTag->type = kTagTypeInteger;
tmpTag->type = kTagTypeInteger;
tmpTag->string = (char *)integer;
tmpTag->tag = 0;
tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
tmpTag->tagNext = 0;
*tag = tmpTag;
return length;
tmpTag->tagNext = 0;
*tag = tmpTag;
return length;
}
//==========================================================================
static long
ParseTagData( char * buffer, TagPtr * tag )
{
int actuallen = 0;
long length;
TagPtr tmpTag;
int actuallen = 0;
long length;
TagPtr tmpTag;
length = FixDataMatchingTag(buffer, kXMLTagData);
if (length == -1) return -1;
tmpTag = NewTag();
if (tmpTag == 0) return -1;
length = FixDataMatchingTag(buffer, kXMLTagData);
if (length == -1) return -1;
tmpTag = NewTag();
if (tmpTag == 0) return -1;
//printf("ParseTagData unimplimented\n");
//printf("Data: %s\n", buffer);
//getchar();
char* string = BASE64Decode(buffer, strlen(buffer), &actuallen);
tmpTag->type = kTagTypeData;
tmpTag->string = string;
tmpTag->tag = 0;
tmpTag->type = kTagTypeData;
tmpTag->string = string;
tmpTag->tag = 0;
tmpTag->offset = actuallen; // buffer_start ? buffer - buffer_start: 0;
tmpTag->tagNext = 0;
*tag = tmpTag;
return length;
tmpTag->tagNext = 0;
*tag = tmpTag;
return length;
}
//==========================================================================
static long
ParseTagDate( char * buffer, TagPtr * tag )
{
long length;
TagPtr tmpTag;
length = FixDataMatchingTag(buffer, kXMLTagDate);
if (length == -1) return -1;
tmpTag = NewTag();
if (tmpTag == 0) return -1;
long length;
TagPtr tmpTag;
length = FixDataMatchingTag(buffer, kXMLTagDate);
if (length == -1) return -1;
tmpTag = NewTag();
if (tmpTag == 0) return -1;
printf("ParseTagDate unimplimented\n");
getchar();
tmpTag->type = kTagTypeDate;
tmpTag->string = 0;
tmpTag->tag = 0;
tmpTag->type = kTagTypeDate;
tmpTag->string = 0;
tmpTag->tag = 0;
tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
tmpTag->tagNext = 0;
*tag = tmpTag;
return length;
tmpTag->tagNext = 0;
*tag = tmpTag;
return length;
}
//==========================================================================
long
ParseTagBoolean( char * buffer, TagPtr * tag, long type )
{
TagPtr tmpTag;
tmpTag = NewTag();
if (tmpTag == 0) return -1;
tmpTag->type = type;
tmpTag->string = 0;
tmpTag->tag = 0;
TagPtr tmpTag;
tmpTag = NewTag();
if (tmpTag == 0) return -1;
tmpTag->type = type;
tmpTag->string = 0;
tmpTag->tag = 0;
tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
tmpTag->tagNext = 0;
*tag = tmpTag;
return 0;
tmpTag->tagNext = 0;
*tag = tmpTag;
return 0;
}
//==========================================================================
static long
GetNextTag( char * buffer, char ** tag, long * start )
{
long cnt, cnt2;
long cnt, cnt2;
if (tag == 0) return -1;
// Find the start of the tag.
cnt = 0;
while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++;
if (buffer[cnt] == '\0') return -1;
// Find the end of the tag.
cnt2 = cnt + 1;
while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++;
if (buffer[cnt2] == '\0') return -1;
if (tag == 0) return -1;
// Fix the tag data.
*tag = buffer + cnt + 1;
buffer[cnt2] = '\0';
if (start) *start = cnt;
return cnt2 + 1;
// Find the start of the tag.
cnt = 0;
while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++;
if (buffer[cnt] == '\0') return -1;
// Find the end of the tag.
cnt2 = cnt + 1;
while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++;
if (buffer[cnt2] == '\0') return -1;
// Fix the tag data.
*tag = buffer + cnt + 1;
buffer[cnt2] = '\0';
if (start) *start = cnt;
return cnt2 + 1;
}
//==========================================================================
XMLFreeTag( TagPtr tag )
{
#if DOFREE
if (tag == 0) return;
if (tag == 0)
{
return;
}
if (!XMLIsInteger(tag) && tag->string) FreeSymbol(tag->string);
if (!XMLIsInteger(tag) && tag->string)
{
FreeSymbol(tag->string);
}
XMLFreeTag(tag->tag);
XMLFreeTag(tag->tagNext);
XMLFreeTag(tag->tag);
XMLFreeTag(tag->tagNext);
// Clear and free the tag.
tag->type = kTagTypeNone;
tag->string = 0;
tag->tag = 0;
// Clear and free the tag.
tag->type = kTagTypeNone;
tag->string = 0;
tag->tag = 0;
tag->offset = 0;
tag->tagNext = gTagsFree;
gTagsFree = tag;
tag->tagNext = gTagsFree;
gTagsFree = tag;
#else
return;
return;
#endif
}
struct Symbol
{
long refCount;
struct Symbol *next;
char string[];
long refCount;
struct Symbol *next;
char string[];
};
typedef struct Symbol Symbol, *SymbolPtr;
static char *
NewSymbol( char * string )
{
static SymbolPtr lastGuy = 0;
static SymbolPtr lastGuy = 0;
SymbolPtr symbol;
// Look for string in the list of symbols.
symbol = FindSymbol(string, 0);
// Look for string in the list of symbols.
symbol = FindSymbol(string, 0);
// Add the new symbol.
if (symbol == 0)
{
symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string));
if (symbol == 0) //return 0;
stop("NULL symbol!");
// Set the symbol's data.
symbol->refCount = 0;
strcpy(symbol->string, string);
// Add the symbol to the list.
symbol->next = gSymbolsHead;
gSymbolsHead = symbol;
}
// Update the refCount and return the string.
symbol->refCount++;
if (symbol == 0)
{
symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string));
if (symbol == 0) //return 0;
{
stop("NULL symbol!");
}
if (lastGuy && lastGuy->next != 0) stop("last guy not last!");
return symbol->string;
// Set the symbol's data.
symbol->refCount = 0;
strcpy(symbol->string, string);
// Add the symbol to the list.
symbol->next = gSymbolsHead;
gSymbolsHead = symbol;
}
// Update the refCount and return the string.
symbol->refCount++;
if (lastGuy && lastGuy->next != 0)
{
stop("last guy not last!");
}
return symbol->string;
}
//==========================================================================
static void
FreeSymbol( char * string )
{
SymbolPtr symbol, prev;
SymbolPtr symbol, prev;
prev = 0;
// Look for string in the list of symbols.
symbol = FindSymbol(string, &prev);
if (symbol == 0) return;
// Update the refCount.
symbol->refCount--;
if (symbol->refCount != 0) return;
// Remove the symbol from the list.
if (prev != 0) prev->next = symbol->next;
else gSymbolsHead = symbol->next;
// Free the symbol's memory.
free(symbol);
// Look for string in the list of symbols.
symbol = FindSymbol(string, &prev);
if (symbol == 0)
{
return;
}
// Update the refCount.
symbol->refCount--;
if (symbol->refCount != 0)
{
return;
}
// Remove the symbol from the list.
if (prev != 0)
{
prev->next = symbol->next;
}
else
{
gSymbolsHead = symbol->next;
}
// Free the symbol's memory.
free(symbol);
}
#endif
static SymbolPtr
FindSymbol( char * string, SymbolPtr * prevSymbol )
{
SymbolPtr symbol, prev;
SymbolPtr symbol, prev;
symbol = gSymbolsHead;
prev = 0;
symbol = gSymbolsHead;
prev = 0;
while (symbol != 0) {
if (!strcmp(symbol->string, string)) break;
while (symbol != 0)
{
if (!strcmp(symbol->string, string))
{
break;
}
prev = symbol;
symbol = symbol->next;
}
prev = symbol;
symbol = symbol->next;
}
if ((symbol != 0) && (prevSymbol != 0)) *prevSymbol = prev;
return symbol;
if ((symbol != 0) && (prevSymbol != 0))
{
*prevSymbol = prev;
}
return symbol;
}
bool XMLIsType(TagPtr dict, enum xmltype type)
{
if(!dict) return (type == kTagTypeNone);
if(!dict)
{
return (type == kTagTypeNone);
}
return (dict->type == type);
}
/*** Cast functions ***/
bool XMLIsArray(TagPtr entry)
{
return entry && (entry->type == kTagTypeArray);
return entry && (entry->type == kTagTypeArray);
}
TagPtr XMLCastArray(TagPtr dict)
{
if(!dict) return NULL;
if(dict->type == kTagTypeArray) return dict;
else return NULL;
if(!dict)
{
return NULL;
}
if(dict->type == kTagTypeArray)
{
return dict;
}
else
{
return NULL;
}
}
bool XMLIsDict(TagPtr entry)
bool XMLIsData(TagPtr entry)
{
return entry && (entry->type == kTagTypeData);
return entry && (entry->type == kTagTypeData);
}
TagPtr XMLCastDict(TagPtr dict)
{
if(!dict) return NULL;
if(dict->type == kTagTypeDict) return dict;
else return NULL;
if(!dict)
{
return NULL;
}
if(dict->type == kTagTypeDict)
{
return dict;
}
else
{
return NULL;
}
}
bool XMLIsString(TagPtr entry)
{
return entry &&
((entry->type == kTagTypeString) ||
(entry->type == kTagTypeKey));
return entry && ((entry->type == kTagTypeString) || (entry->type == kTagTypeKey));
}
char* XMLCastString(TagPtr dict)
{
if(!dict) return NULL;
if(!dict)
{
return NULL;
}
if((dict->type == kTagTypeString) ||
(dict->type == kTagTypeKey)) return dict->string;
if((dict->type == kTagTypeString) || (dict->type == kTagTypeKey))
{
return dict->string;
}
return NULL;
}
char* XMLCastData(TagPtr dict, int* length)
{
if(!dict) return NULL;
if((dict->type == kTagTypeData) ||
(dict->type == kTagTypeKey))
{
*length = dict->offset;
return dict->string;
}
if(!dict)
{
return NULL;
}
if((dict->type == kTagTypeData) || (dict->type == kTagTypeKey))
{
*length = dict->offset;
return dict->string;
}
*length = 0;
return NULL;
}
long XMLCastStringOffset(TagPtr dict)
{
if(dict &&
((dict->type == kTagTypeString) ||
(dict->type == kTagTypeKey)))
if(dict && ((dict->type == kTagTypeString) || (dict->type == kTagTypeKey)))
{
return dict->offset;
}
bool XMLIsBoolean(TagPtr entry)
{
return entry &&
((entry->type == kTagTypeTrue) ||
(entry->type == kTagTypeFalse));
return entry && ((entry->type == kTagTypeTrue) || (entry->type == kTagTypeFalse));
}
bool XMLCastBoolean(TagPtr dict)
{
if(!dict) return false;
if(dict->type == kTagTypeTrue) return true;
if(!dict)
{
return false;
}
if(dict->type == kTagTypeTrue)
{
return true;
}
return false;
}
//printf("XMLCastInteger: null dict\n");
return 0;
}
if(dict->type == kTagTypeInteger) return (int)(dict->string);
if(dict->type == kTagTypeInteger)
{
return (int)(dict->string);
}
return 0;
}
bool XMLAddTagToDictionary(TagPtr dict, char* key, TagPtr value)
{
if (!dict || dict->type != kTagTypeDict) return false;
if (!dict || dict->type != kTagTypeDict)
{
return false;
}
TagPtr tmpTag;
char* string;
TagPtr tmpTag;
char* string;
tmpTag = NewTag();
if (tmpTag == 0)
{
return false;
}
string = NewSymbol(key);
if (string == 0)
{
XMLFreeTag(tmpTag);
return false;
}
tmpTag->type = kTagTypeKey;
tmpTag->string = string;
tmpTag->tag = value;
tmpTag = NewTag();
if (tmpTag == 0)
{
return false;
}
string = NewSymbol(key);
if (string == 0)
{
XMLFreeTag(tmpTag);
return false;
}
tmpTag->type = kTagTypeKey;
tmpTag->string = string;
tmpTag->tag = value;
tmpTag->offset = 0;
tmpTag->tagNext = 0;
TagPtr tagList = dict->tag;
if(!tagList)
{
// First tag
dict->tag = tmpTag;
return true;
}
while(tagList && tagList->tagNext) tagList = tagList->tagNext;
if(tagList)
{
tagList->tagNext = tmpTag;
return true;
}
tmpTag->tagNext = 0;
XMLFreeTag(tmpTag);
return false;
TagPtr tagList = dict->tag;
if(!tagList)
{
// First tag
dict->tag = tmpTag;
return true;
}
while(tagList && tagList->tagNext) tagList = tagList->tagNext;
if(tagList)
{
tagList->tagNext = tmpTag;
return true;
}
XMLFreeTag(tmpTag);
return false;
}
trunk/i386/libsaio/asm.s
8282
8383
8484
85
85
8686
8787
8888
......
348348
349349
350350
351
351
352352
353353
354354
* New boot0 (boot1 has been deprecated). Booter must now reside in its own partition, no disk label required.
*
* Revision 1.1.1.2 1999/08/04 21:16:57 wsanchez
* Impoort of boot-66
* Import of boot-66
*
* Revision 1.3 1999/08/04 21:12:12 wsanchez
* Update APSL
push %ebp
mov %esp, %ebp
mov 0xc(%ebp), %eax // argument to program
mov 0xc(%ebp), %eax // argument to program - bootargs to mach_kernel
mov 0x8(%ebp), %ecx // entry offset
mov $0x28, %ebx // segment
push %ebx
trunk/i386/libsaio/console.c
5050
5151
5252
53
54
53
54
5555
5656
5757
......
6969
7070
7171
72
73
72
73
7474
7575
7676
......
8383
8484
8585
86
86
8787
8888
8989
......
9999
100100
101101
102
102
103103
104
104105
105
106
106107
108
107109
108110
109111
......
115117
116118
117119
118
120
119121
122
120123
121124
122125
......
129132
130133
131134
132
133
135
134136
135137
136138
137139
138
139
140
140141
141
142
142143
143144
144145
145
146
146147
147148
148149
149150
150
151
151152
152
153
154
155
153
154
155
156
157
156158
157159
158160
......
165167
166168
167169
168
170
169171
170172
171173
172174
173175
174
176
175177
176
178
177179
178
180
179181
182
180183
181184
182185
183186
184187
185
188
186189
190
187191
188
192
189193
194
190195
191196
192197
......
194199
195200
196201
197
202
198203
199204
200205
201206
202
207
203208
204209
205
206
207
210
211
208212
209
213
210214
211
215
216
212217
213218
214219
215220
216221
217
222
218223
224
219225
220
226
221227
228
222229
223230
224231
225232
226233
227234
228
229
235
236
230237
231238
232239
233240
234
235
236
237
241
242
243
244
238245
239
246
240247
248
241249
242
250
243251
244252
245253
extern intvprf(const char * fmt, va_list ap);
bool gVerboseMode;
bool gErrors;
bool gVerboseMode = false;
bool gErrors = false;
/*
* Azi: Doubled available log size; this seems to fix some hangs and instant reboots caused by
struct putc_info //Azi: exists on gui.c & printf.c
{
char * str;
char * last_str;
char * str;
char * last_str;
};
static int
return 0;
}
*(pi->str)++ = c;
return c;
return c;
}
void initBooterLog(void)
va_list ap;
struct putc_info pi;
if (!msgbuf)
if (!msgbuf) {
return;
}
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) {
return;
}
va_start(ap, fmt);
pi.str = cursor;
void setupBooterLog(void)
{
if (!msgbuf)
if (!msgbuf) {
return;
}
Node *node = DT__FindNode("/", false);
if (node)
*/
int putchar(int c)
{
if ( c == '\t' )
{
if ( c == '\t' ) {
for (c = 0; c < 8; c++) bios_putchar(' ');
return c;
}
if ( c == '\n' )
{
if ( c == '\n' ) {
bios_putchar('\r');
}
}
bios_putchar(c);
return c;
return c;
}
int getc()
{
int c = bgetc();
int c = bgetc();
if ((c & 0xff) == 0)
return c;
else
return (c & 0xff);
if ((c & 0xff) == 0) {
return c;
} else {
return (c & 0xff);
}
}
// Read and echo a character from console. This doesn't echo backspace
//if ( c == '\r' ) c = '\n';
//if ( c >= ' ' && c < 0x7f) putchar(c);
return (c);
}
int printf(const char * fmt, ...)
{
va_list ap;
va_list ap;
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
prf(fmt, ap, putchar, 0);
else
} else {
vprf(fmt, ap);
}
{
// Kabyl: BooterLog
struct putc_info pi;
if (!msgbuf)
if (!msgbuf) {
return 0;
}
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) {
return 0;
}
pi.str = cursor;
pi.last_str = 0;
prf(fmt, ap, sputc, &pi);
}
va_end(ap);
return 0;
return 0;
}
int verbose(const char * fmt, ...)
{
va_list ap;
va_list ap;
va_start(ap, fmt);
if (gVerboseMode)
{
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
if (gVerboseMode) {
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
prf(fmt, ap, putchar, 0);
else
} else {
vprf(fmt, ap);
}
}
}
{
// Kabyl: BooterLog
struct putc_info pi;
if (!msgbuf)
if (!msgbuf) {
return 0;
}
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) {
return 0;
}
pi.str = cursor;
pi.last_str = 0;
prf(fmt, ap, sputc, &pi);
cursor += strlen((char *)cursor);
}
va_end(ap);
return(0);
va_end(ap);
return(0);
}
int error(const char * fmt, ...)
{
va_list ap;
gErrors = true;
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
va_list ap;
gErrors = true;
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
prf(fmt, ap, putchar, 0);
else
} else {
vprf(fmt, ap);
}
va_end(ap);
return(0);
return(0);
}
void stop(const char * fmt, ...)
trunk/i386/libsaio/xml.h
2626
2727
2828
29
30
31
32
33
34
35
36
37
38
29
30
31
32
33
34
35
36
37
38
3939
4040
4141
......
4848
4949
5050
51
52
53
54
55
56
57
58
59
60
51
52
53
54
55
56
57
58
59
60
61
62
63
64
6165
62
63
64
6566
6667
6768
......
7172
7273
7374
74
75
76
77
75
76
77
78
7879
7980
8081
#define __LIBSAIO_XML_H
enum xmltype {
kTagTypeNone = 0,
kTagTypeDict,
kTagTypeKey,
kTagTypeString,
kTagTypeInteger,
kTagTypeData,
kTagTypeDate,
kTagTypeFalse,
kTagTypeTrue,
kTagTypeArray
kTagTypeNone = 0,
kTagTypeDict,
kTagTypeKey,
kTagTypeString,
kTagTypeInteger,
kTagTypeData,
kTagTypeDate,
kTagTypeFalse,
kTagTypeTrue,
kTagTypeArray
};
struct string_ref
extern string_ref* ref_strings;
#define kXMLTagPList "plist "
#define kXMLTagDict "dict"
#define kXMLTagKey "key"
#define kXMLTagString "string"
#define kXMLTagInteger "integer"
#define kXMLTagData "data"
#define kXMLTagDate "date"
#define kXMLTagFalse "false/"
#define kXMLTagTrue "true/"
#define kXMLTagArray "array"
#define kXMLTagPList "plist "
#define kXMLTagDict "dict"
#define kXMLTagKey "key"
#define kXMLTagString "string"
#define kXMLTagInteger "integer"
#define kXMLTagData "data"
#define kXMLTagDate "date"
#define kXMLTagFalse "false/"
#define kXMLTagTrue "true/"
#define kXMLTagArray "array"
// for back-references used by libkern serializer
#define kXMLTagReference "reference"
#define kXMLStringID "ID="
#define kXMLStringIDRef "IDREF="
#define kXMLStringID"ID="
#define kXMLStringIDRef "IDREF="
#define kPropCFBundleIdentifier ("CFBundleIdentifier")
#define kPropCFBundleExecutable ("CFBundleExecutable")
#define kPropOSBundleRequired ("OSBundleRequired")
/*
struct Tag {
long type;
char *string;
struct Tag *tag;
struct Tag *tagNext;
long type;
char *string;
struct Tag *tag;
struct Tag *tagNext;
};
typedef struct Tag Tag, *TagPtr;
*/
trunk/i386/libsaio/efi.h
7171
7272
7373
74
7574
76
75
7776
7877
7978
......
8281
8382
8483
85
8684
87
8885
8986
9087
......
118115
119116
120117
118
119
120
121
121122
122123
123124
124125
125126
127
126128
127129
128130
......
141143
142144
143145
144
146
145147
146148
147149
......
160162
161163
162164
163
164
165
166
167
168
169
170
171
172
173
165
166
167
168
169
170
171
172
173
174
175
174176
175177
176
178
177179
178
180
179181
180182
181183
182
184
183185
184
186
185187
186188
187189
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
203205
204206
205207
206
207
208
209
210
208
209
210
211
212
211213
212214
213
214215
215
216
216217
217218
218219
219220
220221
221222
222
223
223224
224
225
225226
226227
227228
228229
229
230
230231
231
232
232233
233234
234235
......
236237
237238
238239
239
240
241
242
243
244
240
241
242
243
244
245
245246
246247
247248
......
263264
264265
265266
266
267
267268
268
269
269270
270271
271272
......
302303
303304
304305
305
306
306307
307
308
308309
309
310
311
310
311
312
312313
313314
314315
......
371372
372373
373374
374
375375
376
377
378
379
380
381
382
376
377
378
379
380
383381
384
385
382
386383
387384
388385
......
404401
405402
406403
407
404
408405
409
410
411
412
413
414
415
406
407
408
409
410
416411
417
418
419
420
421
412
422413
423
424
425
426
427
428
414
415
429416
430
431
432
433
434
435417
418
419
420
421
422
423
424
425
426
436427
437
438
439
440
441
442
428
429
430
431
432
433
443434
444435
445436
446437
447438
448
439
449440
450
451
452
453
454
455
456
457441
458
459
460
461
462
442
463443
464
465
466
467
468
469
444
445
446
447
470448
471
472
473
474
475
449
476450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
477465
478
479
480
481
482
483
466
467
468
469
470
471
484472
485473
486474
......
489477
490478
491479
492
493
480
481
494482
495483
496484
497
498
485
486
499487
500488
501
489
502490
503
491
504492
505493
506494
......
508496
509497
510498
511
499
512500
513
514
501
502
515503
516
517
504
505
518506
519
520
507
508
521509
522
523
510
511
524512
525
526
513
514
527515
528
529
516
517
530518
531519
532520
533521
534
522
535523
536
537
524
525
538526
539
527
528
529
540530
541
542
531
532
543533
544
545
534
535
546536
547
548
537
538
549539
550
551
552
553
554
555
540
541
556542
557543
558544
*/
//
// Modifiers for EFI Runtime and Boot Services
//
#define EFI_RUNTIMESERVICE
#define EFIAPI
#define IN
#define EFI_MAX_BIT 0x80000000
//
// Set the upper bit to indicate EFI Error.
//
#define EFIERR(a) (EFI_MAX_BIT | (a))
#define EFIWARN(a) (a)
#define EFI_INCOMPATIBLE_VERSION EFIERR (25)
#define EFI_SECURITY_VIOLATION EFIERR (26)
#define EFI_CRC_ERROR EFIERR (27)
#define EFI_END_OF_MEDIA EFIERR (28)
#define EFI_END_OF_FILE EFIERR (31)
#define EFI_INVALID_LANGUAGE EFIERR (32)
#define EFI_COMPROMISED_DATA EFIERR (33)
#define EFI_WARN_UNKNOWN_GLYPH EFIWARN (1)
#define EFI_WARN_DELETE_FAILURE EFIWARN (2)
#define EFI_WARN_WRITE_FAILURE EFIWARN (3)
#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN (4)
#define EFI_WARN_STALE_DATA EFIWARN (5)
//
// EFI Specification Revision information
{0xAC39C713, 0x7E50, 0x423D, {0x88, 0x9D, 0x27,0x8F, 0xCC, 0x34, 0x22, 0xB6} }
#define EFI_GLOBAL_VARIABLE_GUID \
{0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} }
{0x8BE4DF61, 0x93CA, 0x11D2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} }
typedef union {
EFI_GUID Guid;
// TimeZone: -1440 to 1440 or 2047
//
typedef struct {
EFI_UINT16 Year;
EFI_UINT8 Month;
EFI_UINT8 Day;
EFI_UINT8 Hour;
EFI_UINT8 Minute;
EFI_UINT8 Second;
EFI_UINT8 Pad1;
EFI_UINT32 Nanosecond;
EFI_INT16 TimeZone;
EFI_UINT8 Daylight;
EFI_UINT8 Pad2;
EFI_UINT16 Year;
EFI_UINT8 Month;
EFI_UINT8 Day;
EFI_UINT8 Hour;
EFI_UINT8 Minute;
EFI_UINT8 Second;
EFI_UINT8 Pad1;
EFI_UINT32 Nanosecond;
EFI_INT16 TimeZone;
EFI_UINT8 Daylight;
EFI_UINT8 Pad2;
} EFI_TIME;
//
// Bit definitions for EFI_TIME.Daylight
//
#define EFI_TIME_ADJUST_DAYLIGHT 0x01
#define EFI_TIME_IN_DAYLIGHT 0x02
//
// Value definition for EFI_TIME.TimeZone
//
#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
typedef enum {
EfiReservedMemoryType,
EfiLoaderCode,
EfiLoaderData,
EfiBootServicesCode,
EfiBootServicesData,
EfiRuntimeServicesCode,
EfiRuntimeServicesData,
EfiConventionalMemory,
EfiUnusableMemory,
EfiACPIReclaimMemory,
EfiACPIMemoryNVS,
EfiMemoryMappedIO,
EfiMemoryMappedIOPortSpace,
EfiPalCode,
EfiMaxMemoryType
EfiReservedMemoryType,
EfiLoaderCode,
EfiLoaderData,
EfiBootServicesCode,
EfiBootServicesData,
EfiRuntimeServicesCode,
EfiRuntimeServicesData,
EfiConventionalMemory,
EfiUnusableMemory,
EfiACPIReclaimMemory,
EfiACPIMemoryNVS,
EfiMemoryMappedIO,
EfiMemoryMappedIOPortSpace,
EfiPalCode,
EfiMaxMemoryType
} EFI_MEMORY_TYPE;
typedef struct {
EFI_UINT64 Signature;
EFI_UINT32 Revision;
EFI_UINT32 HeaderSize;
EFI_UINT32 CRC32;
EFI_UINT32 Reserved;
EFI_UINT64Signature;
EFI_UINT32Revision;
EFI_UINT32HeaderSize;
EFI_UINT32CRC32;
EFI_UINT32Reserved;
} __attribute__((aligned(8))) EFI_TABLE_HEADER;
//
// possible caching types for the memory range
//
#define EFI_MEMORY_UC 0x0000000000000001ULL
#define EFI_MEMORY_WC 0x0000000000000002ULL
#define EFI_MEMORY_WT 0x0000000000000004ULL
#define EFI_MEMORY_WB 0x0000000000000008ULL
#define EFI_MEMORY_UCE 0x0000000000000010ULL
//
// physical memory protection on range
//
#define EFI_MEMORY_WP 0x0000000000001000ULL
#define EFI_MEMORY_RP 0x0000000000002000ULL
#define EFI_MEMORY_XP 0x0000000000004000ULL
//
// range requires a runtime mapping
//
#define EFI_MEMORY_RUNTIME 0x8000000000000000ULL
typedef EFI_UINT64 EFI_PHYSICAL_ADDRESS;
#define EFI_MEMORY_DESCRIPTOR_VERSION 1
typedef struct {
EFI_UINT32 Type;
EFI_UINT32 Pad;
EFI_PHYSICAL_ADDRESS PhysicalStart;
EFI_VIRTUAL_ADDRESS VirtualStart;
EFI_UINT64 NumberOfPages;
EFI_UINT64 Attribute;
EFI_UINT32 Type;
EFI_UINT32 Pad;
EFI_PHYSICAL_ADDRESS PhysicalStart;
EFI_VIRTUAL_ADDRESS VirtualStart;
EFI_UINT64 NumberOfPages;
EFI_UINT64 Attribute;
} __attribute__((aligned(8))) EFI_MEMORY_DESCRIPTOR;
IN OUT VOID **Address
) __attribute__((regparm(0)));
//
// Variable attributes
//
#define EFI_VARIABLE_NON_VOLATILE 0x00000001
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
IN VOID * Data
) __attribute__((regparm(0)));
//
// EFI Time
//
typedef struct {
EFI_UINT32 Resolution;
EFI_UINT32 Accuracy;
EFI_BOOLEAN SetsToZero;
EFI_UINT32 Resolution;
EFI_UINT32 Accuracy;
EFI_BOOLEAN SetsToZero;
} __attribute__((aligned(4))) EFI_TIME_CAPABILITIES;
typedef
OUT EFI_UINT32 * HighCount
) __attribute__((regparm(0)));
//
// Definition of Status Code extended data header
//
// HeaderSize The size of the architecture. This is specified to enable
// the future expansion
//
// Size The size of the data in bytes. This does not include the size
// of the header structure.
//
// HeaderSize The size of the architecture. This is specified to enable the future expansion
// Size The size of the data in bytes. This does not include the size of the header structure.
// Type A GUID defining the type of the data
//
//
#ifdef TIANO_EXTENSION_FLAG
typedef
#define EFI_RUNTIME_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION << 16) | (EFI_SPECIFICATION_MINOR_REVISION))
typedef struct {
EFI_TABLE_HEADER Hdr;
EFI_TABLE_HEADERHdr;
//
// Time services
//
EFI_PTR32 GetTime;
EFI_PTR32 SetTime;
EFI_PTR32 GetWakeupTime;
EFI_PTR32 SetWakeupTime;
// Time Services
EFI_PTR32GetTime;
EFI_PTR32SetTime;
EFI_PTR32GetWakeupTime;
EFI_PTR32SetWakeupTime;
//
// Virtual memory services
//
EFI_PTR32 SetVirtualAddressMap;
EFI_PTR32 ConvertPointer;
// Virtual Memory Services
//
// Variable services
//
EFI_PTR32 GetVariable;
EFI_PTR32 GetNextVariableName;
EFI_PTR32 SetVariable;
EFI_PTR32 SetVirtualAddressMap;
EFI_PTR32 ConvertPointer;
//
// Misc
//
EFI_PTR32 GetNextHighMonotonicCount;
EFI_PTR32 ResetSystem;
// Variable Services
EFI_PTR32 GetVariable;
EFI_PTR32 GetNextVariableName;
EFI_PTR32 SetVariable;
// Miscellaneous Services
EFI_PTR32 GetNextHighMonotonicCount;
EFI_PTR32 ResetSystem;
#ifdef TIANO_EXTENSION_FLAG
//
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
//
EFI_PTR32 ReportStatusCode;
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
EFI_PTR32 ReportStatusCode;
#endif
} __attribute__((aligned(8))) EFI_RUNTIME_SERVICES_32;
typedef struct {
EFI_TABLE_HEADER Hdr;
EFI_TABLE_HEADER Hdr;
//
// Time services
//
EFI_PTR64 GetTime;
EFI_PTR64 SetTime;
EFI_PTR64 GetWakeupTime;
EFI_PTR64 SetWakeupTime;
//
// Virtual memory services
//
EFI_PTR64 SetVirtualAddressMap;
EFI_PTR64 ConvertPointer;
// Time services
//
// Variable services
//
EFI_PTR64 GetVariable;
EFI_PTR64 GetNextVariableName;
EFI_PTR64 SetVariable;
EFI_PTR64 GetTime;
EFI_PTR64 SetTime;
EFI_PTR64 GetWakeupTime;
EFI_PTR64 SetWakeupTime;
//
// Misc
//
EFI_PTR64 GetNextHighMonotonicCount;
EFI_PTR64 ResetSystem;
// Virtual memory services
EFI_PTR64 SetVirtualAddressMap;
EFI_PTR64 ConvertPointer;
// Variable services
EFI_PTR64 GetVariable;
EFI_PTR64 GetNextVariableName;
EFI_PTR64 SetVariable;
// Misc
EFI_PTR64 GetNextHighMonotonicCount;
EFI_PTR64 ResetSystem;
#ifdef TIANO_EXTENSION_FLAG
//
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
//
EFI_PTR64 ReportStatusCode;
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
EFI_PTR64 ReportStatusCode;
#endif
} __attribute__((aligned(8))) EFI_RUNTIME_SERVICES_64;
// EFI Configuration Table
//
typedef struct {
EFI_GUID VendorGuid;
EFI_PTR32 VendorTable;
EFI_GUID VendorGuid;
EFI_PTR32 VendorTable;
} EFI_CONFIGURATION_TABLE_32;
typedef struct {
EFI_GUID VendorGuid;
EFI_PTR64 VendorTable;
EFI_GUID VendorGuid;
EFI_PTR64 VendorTable;
} __attribute__((aligned(8))) EFI_CONFIGURATION_TABLE_64;
//
// EFI System Table
//
#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249ULL
#define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION << 16) | (EFI_SPECIFICATION_MINOR_REVISION))
#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | 00)
#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | 10)
typedef struct EFI_SYSTEM_TABLE_32 {
EFI_TABLE_HEADER Hdr;
EFI_TABLE_HEADER Hdr;
EFI_PTR32 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_PTR32 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_HANDLE32 ConsoleInHandle;
EFI_PTR32 ConIn;
EFI_HANDLE32 ConsoleInHandle;
EFI_PTR32 ConIn;
EFI_HANDLE32 ConsoleOutHandle;
EFI_PTR32 ConOut;
EFI_HANDLE32 ConsoleOutHandle;
EFI_PTR32 ConOut;
EFI_HANDLE32 StandardErrorHandle;
EFI_PTR32 StdErr;
EFI_HANDLE32 StandardErrorHandle;
EFI_PTR32 StdErr;
EFI_PTR32 RuntimeServices;
EFI_PTR32 BootServices;
EFI_PTR32 RuntimeServices;
EFI_PTR32 BootServices;
EFI_UINT32 NumberOfTableEntries;
EFI_PTR32 ConfigurationTable;
EFI_UINT32 NumberOfTableEntries;
EFI_PTR32 ConfigurationTable;
} __attribute__((aligned(8))) EFI_SYSTEM_TABLE_32;
typedef struct EFI_SYSTEM_TABLE_64 {
EFI_TABLE_HEADER Hdr;
EFI_TABLE_HEADER Hdr;
EFI_PTR64 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_PTR64 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_UINT32 __pad;
EFI_UINT32 __pad;
EFI_HANDLE64 ConsoleInHandle;
EFI_PTR64 ConIn;
EFI_HANDLE64 ConsoleInHandle;
EFI_PTR64 ConIn;
EFI_HANDLE64 ConsoleOutHandle;
EFI_PTR64 ConOut;
EFI_HANDLE64 ConsoleOutHandle;
EFI_PTR64 ConOut;
EFI_HANDLE64 StandardErrorHandle;
EFI_PTR64 StdErr;
EFI_HANDLE64 StandardErrorHandle;
EFI_PTR64 StdErr;
EFI_PTR64 RuntimeServices;
EFI_PTR64 BootServices;
EFI_PTR64 RuntimeServices;
EFI_PTR64 BootServices;
EFI_UINT64 NumberOfTableEntries;
EFI_PTR64 ConfigurationTable;
EFI_UINT64 NumberOfTableEntries;
EFI_PTR64 ConfigurationTable;
} __attribute__((aligned(8))) EFI_SYSTEM_TABLE_64;
#endif /* _PEXPERT_I386_EFI_H */
trunk/i386/libsaio/bootstruct.h
4444
4545
4646
47
4847
4948
5049
......
7574
7675
7776
78
79
80
77
78
79
8180
8281
8382
......
9190
9291
9392
94
95
96
97
93
94
95
96
9897
99
98
10099
101100
102101
......
108107
109108
110109
111
112
110
111
113112
114
113
115114
116
115
117116
118
119
117
118
120119
121
120
122121
123122
124
123
125124
126
127
125
126
128127
129
130
131
132
133
134
128
129
130
131
132
133
135134
136135
137136
//#define FB_TEXT_MODE 2
/*
* Maximum number of boot drivers that can be loaded.
*/
} PCI_bus_info_t;
typedef struct {
unsigned long address; // address where driver was loaded
unsigned long size; // number of bytes
unsigned long type; // driver type
unsigned long address; // address where driver was loaded
unsigned long size; // number of bytes
unsigned long type; // driver type
} driver_config_t;
/*
* ACPI defined memory range types.
*/
enum {
kMemoryRangeUsable = 1, // RAM usable by the OS.
kMemoryRangeReserved = 2, // Reserved. (Do not use)
kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed.
kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use)
kMemoryRangeUsable = 1, // RAM usable by the OS.
kMemoryRangeReserved = 2, // Reserved. (Do not use)
kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed.
kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use)
/* Undefined types should be treated as kMemoryRangeReserved */
/* Undefined types should be treated as kMemoryRangeReserved */
};
/*!
to the kernel and are thus located in bootArgs although with different field names.
*/
typedef struct PrivateBootInfo {
int convmem; // conventional memory
int extmem; // extended memory
int convmem; // conventional memory
int extmem; // extended memory
#if 0
int numBootDrivers; // number of drivers loaded
int numBootDrivers; // number of drivers loaded
#endif
char bootFile[128]; // kernel file name
char bootFile[128]; // kernel file name
unsigned long memoryMapCount;
MemoryRange memoryMap[kMemoryMapCountMax];
unsigned long memoryMapCount;
MemoryRange memoryMap[kMemoryMapCountMax];
PCI_bus_info_t pciInfo;
PCI_bus_info_t pciInfo;
#if 0
driver_config_t driverConfig[NDRIVERS];
driver_config_t driverConfig[NDRIVERS];
#endif
char * configEnd; // pointer to end of config files
char config[CONFIG_SIZE];
char * configEnd;// pointer to end of config files
char config[CONFIG_SIZE];
config_file_t bootConfig; // com.apple.Boot.plist
config_file_t chameleonConfig; // org.chameleon.Boot.plist which can override bootConfig keys
config_file_t themeConfig; // theme.plist
config_file_t smbiosConfig; // smbios.plist
config_file_t helperConfig; // boot helper partition's boot.plist
config_file_t ramdiskConfig; // RAMDisk.plist
config_file_t bootConfig;// com.apple.Boot.plist
config_file_t chameleonConfig;// org.chameleon.Boot.plist which can override bootConfig keys
config_file_t themeConfig;// theme.plist
config_file_t smbiosConfig;// smbios.plist
config_file_t helperConfig;// boot helper partition's boot.plist
config_file_t ramdiskConfig;// RAMDisk.plist
bool memDetect;
} PrivateBootInfo_t;
trunk/i386/libsaio/device_tree.c
11
2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
320
421
522
623
7
24
825
926
1027
1128
1229
1330
14
15
31
32
1633
1734
1835
1936
2037
21
22
38
39
2340
2441
2542
2643
2744
28
45
46
2947
3048
3149
......
4967
5068
5169
52
53
54
70
71
72
5573
5674
5775
......
6179
6280
6381
82
83
84
6485
6586
6687
67
88
6889
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
90
9291
93
94
95
92
93
94
9695
97
98
99
100
101
102
103
104
96
10597
106
107
108
109
98
99
100
110101
111
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
112141
113142
143
144
145
114146
115147
116148
117
149
118150
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
151
152
153
144154
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
155204
156205
206
207
208
157209
158210
159211
160
161
212
213
162214
215
216
217
163218
164219
165220
......
167222
168223
169224
225
226
170227
171228
172229
173
174
175
176
177
178
179
180
181
182
183
184
185
230
231
232
233
234
235
236
237
238
239
240
241
242
186243
187244
245
188246
189
190
247
191248
192249
193250
194251
195
196
252
253
197254
198
199
200
201
202
203
255
204256
205
206
207
208
209
210
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
211273
212
213
214
215
216
274
275
276
277
217278
218279
280
281
219282
220283
221284
222
223
224
225
285
286
287
288
226289
227
290
291
292
228293
229
230
294
295
231296
232
233
234
235
236
237
238
239
240
297
298
299
300
301
302
303
304
305
241306
242
243
244
245
307
246308
247
309
310
311
312
313
314
315
316
248317
249318
250
251
252
319
320
321
253322
254323
255324
......
258327
259328
260329
261
262
330
331
263332
264
333
334
265335
266
336
337
338
267339
268340
269
270
271
341
342
343
272344
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
291376
292377
378
379
293380
294381
295382
296
383
297384
298
299
300
301
302
303
304
305
306
307
385
386
387
388
389
390
391
392
393
394
395
396
397
308398
309399
400
401
310402
311403
312404
313
314
315
316
405
406
407
408
317409
318
410
319411
320
321
322
412
413
323414
324
325
326
415
327416
328
329
417
418
419
420
421
422
423
330424
331
332
333
334
335
425
426
427
428
336429
337
338
339
340
341
342
343
344
345
346
347
430
348431
349
350
351
352
353
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
354465
355466
356467
357468
469
470
358471
359472
360473
361
362
474
475
363476
364
365
366
477
478
479
480
367481
368
369
370
371
372
373
374
375
376
377
378
379
380
381
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
382505
383506
507
508
384509
385510
386511
387
388
389
390
512
513
514
515
516
517
518
519
391520
392521
522
523
393524
394525
395526
396
397
527
528
398529
399530
531
532
400533
401534
402535
403
404
405
406
407
536
537
538
539
540
408541
409
410
411
542
543
544
412545
413
414
415
416
417
418
419
420
421
422
423
546
547
548
549
550
551
552
553
554
555
556
557
558
424559
425
560
426561
427562
563
564
428565
429566
430567
431
568
432569
433
570
434571
435
436
437
438
439
440
441
442
443
572
573
574
575
576
577
578
579
580
581
582
444583
445584
585
586
446587
447588
448589
449
590
450591
451592
593
452594
453595
454596
455597
456
457
458
459
460
461
462
463
598
599
600
601
602
603
604
605
464606
465
607
466608
467
468
469
470
609
610
611
612
471613
472
473
474
475
614
615
616
617
476618
477
478
479
480
619
620
621
622
481623
482
483
624
625
484626
485
627
486628
487
629
488630
489
631
490632
491
633
492634
493
635
494636
495
637
496638
497
639
498640
499
641
500642
501
502
503
504
643
644
645
646
647
648
649
650
651
652
653
505654
506
507
508
509
510
511
512
655
656
513657
514
515
516
517
518
519
658
659
660
661
662
663
664
665
520666
521
522
523
524
525
526
527
528
529
530
531
532
533
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
534682
535683
536
684
537685
538686
539687
/*
* Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved.
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
*/
#if 1
/*
Structures for a Flattened Device Tree
*/
#define kPropNameLength 32
typedef struct DeviceTreeNodeProperty {
char name[kPropNameLength]; // NUL terminated property name
unsigned long length; // Length (bytes) of folloing prop value
char name[kPropNameLength]; // NUL terminated property name
unsigned long length; // Length (bytes) of folloing prop value
// unsigned long value[1]; // Variable length value of property
// Padded to a multiple of a longword?
} DeviceTreeNodeProperty;
typedef struct OpaqueDTEntry {
unsigned long nProperties; // Number of props[] elements (0 => end)
unsigned long nChildren; // Number of children[] elements
unsigned long nProperties; // Number of props[] elements (0 => end)
unsigned long nChildren; // Number of children[] elements
// DeviceTreeNodeProperty props[];// array size == nProperties
// DeviceTreeNode children[]; // array size == nChildren
} DeviceTreeNode;
typedef char DTPropertyNameBuf[32];
/* Entry Name Definitions (Entry Names are C-Strings)*/
// Entry Name Definitions (Entry Names are C-Strings).
enum {
kDTMaxEntryNameLength = 31 /* Max length of a C-String Entry Name (terminator not included) */
};
#define RoundToLong(x)(((x) + 3) & ~3)
static struct _DTSizeInfo {
uint32_t numNodes;
uint32_t numProperties;
uint32_t totalPropertySize;
uint32_tnumNodes;
uint32_tnumProperties;
uint32_ttotalPropertySize;
} DTInfo;
#define kAllocSize 4096
static Node *freeNodes, *allocedNodes;
static Property *freeProperties, *allocedProperties;
//==============================================================================
Property *
DT__AddProperty(Node *node, const char *name, uint32_t length, void *value)
{
Property *prop;
Property *prop;
DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value);
if (freeProperties == NULL) {
void *buf = malloc(kAllocSize);
int i;
DPRINTF("Allocating more free properties\n");
if (buf == 0) return 0;
bzero(buf, kAllocSize);
// Use the first property to record the allocated buffer
// for later freeing.
prop = (Property *)buf;
prop->next = allocedProperties;
allocedProperties = prop;
prop->value = buf;
prop++;
for (i=1; i<(kAllocSize / sizeof(Property)); i++) {
prop->next = freeProperties;
freeProperties = prop;
prop++;
}
}
prop = freeProperties;
freeProperties = prop->next;
DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value);
prop->name = name;
prop->length = length;
prop->value = value;
if (freeProperties == NULL) {
void *buf = malloc(kAllocSize);
int i;
// Always add to end of list
if (node->properties == 0) {
node->properties = prop;
} else {
node->last_prop->next = prop;
}
node->last_prop = prop;
prop->next = 0;
DPRINTF("Allocating more free properties\n");
DPRINTF("Done [0x%x]\n", prop);
DTInfo.numProperties++;
DTInfo.totalPropertySize += RoundToLong(length);
if (buf == 0) {
return 0;
}
return prop;
bzero(buf, kAllocSize);
// Use the first property to record the allocated buffer
// for later freeing.
prop = (Property *)buf;
prop->next = allocedProperties;
allocedProperties = prop;
prop->value = buf;
prop++;
for (i = 1; i < (kAllocSize / sizeof(Property)); i++) {
prop->next = freeProperties;
freeProperties = prop;
prop++;
}
}
prop = freeProperties;
freeProperties = prop->next;
prop->name = name;
prop->length = length;
prop->value = value;
// Always add to end of list
if (node->properties == 0) {
node->properties = prop;
} else {
node->last_prop->next = prop;
}
node->last_prop = prop;
prop->next = 0;
DPRINTF("Done [0x%x]\n", prop);
DTInfo.numProperties++;
DTInfo.totalPropertySize += RoundToLong(length);
return prop;
}
//==============================================================================
Node *
DT__AddChild(Node *parent, const char *name)
{
Node *node;
Node *node;
if (freeNodes == NULL) {
void *buf = malloc(kAllocSize);
int i;
DPRINTF("Allocating more free nodes\n");
if (buf == 0) return 0;
bzero(buf, kAllocSize);
node = (Node *)buf;
// Use the first node to record the allocated buffer
// for later freeing.
node->next = allocedNodes;
allocedNodes = node;
node->children = (Node *)buf;
node++;
for (i=1; i<(kAllocSize / sizeof(Node)); i++) {
node->next = freeNodes;
freeNodes = node;
node++;
}
}
DPRINTF("DT__AddChild(0x%x, '%s')\n", parent, name);
node = freeNodes;
freeNodes = node->next;
DPRINTF("Got free node 0x%x\n", node);
DPRINTF("prop = 0x%x, children = 0x%x, next = 0x%x\n", node->properties, node->children, node->next);
if (freeNodes == NULL)
{
void *buf = malloc(kAllocSize);
if (parent == NULL) {
rootNode = node;
node->next = 0;
} else {
node->next = parent->children;
parent->children = node;
}
DTInfo.numNodes++;
DT__AddProperty(node, "name", strlen(name) + 1, (void *) name);
return node;
if (buf == 0)
{
return 0;
}
int i;
DPRINTF("Allocating more free nodes\n");
bzero(buf, kAllocSize);
node = (Node *)buf;
// Use the first node to record the allocated buffer for later freeing.
node->next = allocedNodes;
allocedNodes = node;
node->children = (Node *)buf;
node++;
for (i = 1; i < (kAllocSize / sizeof(Node)); i++)
{
node->next = freeNodes;
freeNodes = node;
node++;
}
}
DPRINTF("DT__AddChild(0x%x, '%s')\n", parent, name);
node = freeNodes;
freeNodes = node->next;
DPRINTF("Got free node 0x%x\n", node);
DPRINTF("prop = 0x%x, children = 0x%x, next = 0x%x\n", node->properties, node->children, node->next);
if (parent == NULL)
{
rootNode = node;
node->next = 0;
}
else
{
node->next = parent->children;
parent->children = node;
}
DTInfo.numNodes++;
DT__AddProperty(node, "name", strlen(name) + 1, (void *) name);
return node;
}
//==============================================================================
void
DT__FreeProperty(Property *prop)
{
prop->next = freeProperties;
freeProperties = prop;
prop->next = freeProperties;
freeProperties = prop;
}
//==============================================================================
void
DT__FreeNode(Node *node)
{
freeNodes = node;
}
//==============================================================================
void
DT__Initialize(void)
{
DPRINTF("DT__Initialize\n");
freeNodes = 0;
allocedNodes = 0;
freeProperties = 0;
allocedProperties = 0;
DTInfo.numNodes = 0;
DTInfo.numProperties = 0;
DTInfo.totalPropertySize = 0;
rootNode = DT__AddChild(NULL, "/");
DPRINTF("DT__Initialize done\n");
DPRINTF("DT__Initialize\n");
freeNodes = 0;
allocedNodes = 0;
freeProperties = 0;
allocedProperties = 0;
DTInfo.numNodes = 0;
DTInfo.numProperties = 0;
DTInfo.totalPropertySize = 0;
rootNode = DT__AddChild(NULL, "/");
DPRINTF("DT__Initialize done\n");
}
//==============================================================================
/*
* Free up memory used by in-memory representation
* of device tree.
* Free up memory used by in-memory representation of device tree.
*/
void
DT__Finalize(void)
{
Node *node;
Property *prop;
Node *node;
Property *prop;
DPRINTF("DT__Finalize\n");
for (prop = allocedProperties; prop != NULL; prop = prop->next) {
free(prop->value);
}
allocedProperties = NULL;
freeProperties = NULL;
DPRINTF("DT__Finalize\n");
for (node = allocedNodes; node != NULL; node = node->next) {
free((void *)node->children);
}
allocedNodes = NULL;
freeNodes = NULL;
rootNode = NULL;
for (prop = allocedProperties; prop != NULL; prop = prop->next)
{
free(prop->value);
}
allocedProperties = NULL;
freeProperties = NULL;
for (node = allocedNodes; node != NULL; node = node->next)
{
free((void *)node->children);
}
allocedNodes = NULL;
freeNodes = NULL;
rootNode = NULL;
// XXX leaks any created strings
DTInfo.numNodes = 0;
DTInfo.numProperties = 0;
DTInfo.totalPropertySize = 0;
// XXX leaks any created strings
DTInfo.numNodes = 0;
DTInfo.numProperties = 0;
DTInfo.totalPropertySize = 0;
}
//==============================================================================
static void *
FlattenNodes(Node *node, void *buffer)
{
Property *prop;
DeviceTreeNode *flatNode;
DeviceTreeNodeProperty *flatProp;
int count;
Property *prop;
DeviceTreeNode *flatNode;
DeviceTreeNodeProperty *flatProp;
int count;
if (node == 0) return buffer;
if (node == 0) {
return buffer;
}
flatNode = (DeviceTreeNode *)buffer;
buffer += sizeof(DeviceTreeNode);
flatNode = (DeviceTreeNode *)buffer;
buffer += sizeof(DeviceTreeNode);
for (count = 0, prop = node->properties; prop != 0; count++, prop = prop->next) {
flatProp = (DeviceTreeNodeProperty *)buffer;
strcpy(flatProp->name, prop->name);
flatProp->length = prop->length;
buffer += sizeof(DeviceTreeNodeProperty);
bcopy(prop->value, buffer, prop->length);
buffer += RoundToLong(prop->length);
}
flatNode->nProperties = count;
for (count = 0, prop = node->properties; prop != 0; count++, prop = prop->next)
{
flatProp = (DeviceTreeNodeProperty *)buffer;
strcpy(flatProp->name, prop->name);
flatProp->length = prop->length;
buffer += sizeof(DeviceTreeNodeProperty);
bcopy(prop->value, buffer, prop->length);
buffer += RoundToLong(prop->length);
}
for (count = 0, node = node->children; node != 0; count++, node = node->next) {
buffer = FlattenNodes(node, buffer);
}
flatNode->nChildren = count;
flatNode->nProperties = count;
return buffer;
for (count = 0, node = node->children; node != 0; count++, node = node->next)
{
buffer = FlattenNodes(node, buffer);
}
flatNode->nChildren = count;
return buffer;
}
/*
* Flatten the in-memory representation of the device tree
* into a binary DT block.
/*==============================================================================
* Flatten the in-memory representation of the device tree into a binary DT block.
* To get the buffer size needed, call with result = 0.
* To have a buffer allocated for you, call with *result = 0.
* To use your own buffer, call with *result = &buffer.
void
DT__FlattenDeviceTree(void **buffer_p, uint32_t *length)
{
uint32_t totalSize;
void *buf;
uint32_t totalSize;
void * buf;
DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length);
DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length);
#if DEBUG
if (buffer_p) DT__PrintTree(rootNode);
if (buffer_p) {
DT__PrintTree(rootNode);
}
#endif
totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) +
DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) +
DTInfo.totalPropertySize;
totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) +
DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) +
DTInfo.totalPropertySize;
DPRINTF("Total size 0x%x\n", totalSize);
if (buffer_p != 0) {
if (totalSize == 0) {
buf = 0;
} else {
if (*buffer_p == 0) {
buf = malloc(totalSize);
} else {
buf = *buffer_p;
}
bzero(buf, totalSize);
FlattenNodes(rootNode, buf);
}
*buffer_p = buf;
}
if (length)
*length = totalSize;
DPRINTF("Total size 0x%x\n", totalSize);
if (buffer_p != 0)
{
if (totalSize == 0)
{
buf = 0;
}
else
{
if (*buffer_p == 0)
{
buf = malloc(totalSize);
}
else
{
buf = *buffer_p;
}
bzero(buf, totalSize);
FlattenNodes(rootNode, buf);
}
*buffer_p = buf;
}
if (length)
{
*length = totalSize;
}
}
//==============================================================================
char *
DT__GetName(Node *node)
{
Property *prop;
Property *prop;
//DPRINTF("DT__GetName(0x%x)\n", node);
//DPRINTF("Node properties = 0x%x\n", node->properties);
for (prop = node->properties; prop; prop = prop->next) {
//DPRINTF("Prop '%s'\n", prop->name);
if (strcmp(prop->name, "name") == 0) {
return prop->value;
}
}
//DPRINTF("DT__GetName returns 0\n");
return "(null)";
//DPRINTF("DT__GetName(0x%x)\n", node);
//DPRINTF("Node properties = 0x%x\n", node->properties);
for (prop = node->properties; prop; prop = prop->next)
{
//DPRINTF("Prop '%s'\n", prop->name);
if (strcmp(prop->name, "name") == 0)
{
return prop->value;
}
}
//DPRINTF("DT__GetName returns 0\n");
return "(null)";
}
//==============================================================================
Node *
DT__FindNode(const char *path, bool createIfMissing)
{
Node *node, *child;
DTPropertyNameBuf nameBuf;
char *bp;
int i;
Node *node, *child;
DTPropertyNameBuf nameBuf;
char *bp;
int i;
DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);
DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);
// Start at root
node = rootNode;
DPRINTF("root = 0x%x\n", rootNode);
// Start at root
node = rootNode;
while (node) {
// Skip leading slash
while (*path == '/') path++;
DPRINTF("root = 0x%x\n", rootNode);
for (i=0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++) *bp = *path;
*bp = '\0';
while (node)
{
// Skip leading slash
while (*path == '/')
{
path++;
}
if (nameBuf[0] == '\0') {
// last path entry
break;
}
DPRINTF("Node '%s'\n", nameBuf);
for (i = 0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++)
{
*bp = *path;
}
for (child = node->children; child != 0; child = child->next) {
DPRINTF("Child 0x%x\n", child);
if (strcmp(DT__GetName(child), nameBuf) == 0) {
break;
}
}
if (child == 0 && createIfMissing) {
DPRINTF("Creating node\n");
char *str = malloc(strlen(nameBuf) + 1);
// XXX this will leak
strcpy(str, nameBuf);
*bp = '\0';
child = DT__AddChild(node, str);
}
node = child;
}
return node;
if (nameBuf[0] == '\0')
{
// last path entry
break;
}
DPRINTF("Node '%s'\n", nameBuf);
for (child = node->children; child != 0; child = child->next)
{
DPRINTF("Child 0x%x\n", child);
if (strcmp(DT__GetName(child), nameBuf) == 0)
{
break;
}
}
if (child == 0 && createIfMissing)
{
DPRINTF("Creating node\n");
char *str = malloc(strlen(nameBuf) + 1);
// XXX this will leak
strcpy(str, nameBuf);
child = DT__AddChild(node, str);
}
node = child;
}
return node;
}
#if DEBUG
//==============================================================================
void
DT__PrintNode(Node *node, int level)
{
char spaces[10], *cp = spaces;
Property *prop;
char spaces[10], *cp = spaces;
Property *prop;
if (level > 9) level = 9;
while (level--) *cp++ = ' ';
*cp = '\0';
if (level > 9)
{
level = 9;
}
printf("%s===Node===\n", spaces);
for (prop = node->properties; prop; prop = prop->next) {
char c = *((char *)prop->value);
if (prop->length < 64 && (
strcmp(prop->name, "name") == 0 ||
(c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') || c == '_')) {
printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value);
} else {
printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length);
}
}
printf("%s==========\n", spaces);
while (level--)
{
*cp++ = ' ';
}
*cp = '\0';
printf("%s===Node===\n", spaces);
for (prop = node->properties; prop; prop = prop->next)
{
char c = *((char *)prop->value);
if (prop->length < 64 && (strcmp(prop->name, "name") == 0 || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'))
{
printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value);
}
else
{
printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length);
}
}
printf("%s==========\n", spaces);
}
//==============================================================================
static void
_PrintTree(Node *node, int level)
{
DT__PrintNode(node, level);
level++;
for (node = node->children; node; node = node->next)
_PrintTree(node, level);
DT__PrintNode(node, level);
level++;
for (node = node->children; node; node = node->next)
{
_PrintTree(node, level);
}
}
//==============================================================================
void
DT__PrintTree(Node *node)
{
if (node == 0) node = rootNode;
_PrintTree(node, 0);
if (node == 0) node = rootNode;
_PrintTree(node, 0);
}
//==============================================================================
void
DT__PrintFlattenedNode(DTEntry entry, int level)
{
char spaces[10], *cp = spaces;
DTPropertyIterator propIter;
char *name;
void *prop;
int propSize;
char spaces[10], *cp = spaces;
DTPropertyIterator propIter;
char *name;
void *prop;
int propSize;
if (level > 9) level = 9;
while (level--) *cp++ = ' ';
*cp = '\0';
if (level > 9) level = 9;
while (level--) *cp++ = ' ';
*cp = '\0';
printf("%s===Entry %p===\n", spaces, entry);
if (kSuccess != DTCreatePropertyIterator(entry, &propIter)) {
printf("Couldn't create property iterator\n");
return;
}
while( kSuccess == DTIterateProperties( propIter, &name)) {
if( kSuccess != DTGetProperty( entry, name, &prop, &propSize ))
continue;
printf("%s Property %s = %s\n", spaces, name, prop);
}
DTDisposePropertyIterator(propIter);
printf("%s===Entry %p===\n", spaces, entry);
if (kSuccess != DTCreatePropertyIterator(entry, &propIter))
{
printf("Couldn't create property iterator\n");
return;
}
while( kSuccess == DTIterateProperties( propIter, &name))
{
if( kSuccess != DTGetProperty( entry, name, &prop, &propSize ))
continue;
printf("%s Property %s = %s\n", spaces, name, prop);
}
DTDisposePropertyIterator(propIter);
printf("%s==========\n", spaces);
printf("%s==========\n", spaces);
}
//==============================================================================
static void
_PrintFlattenedTree(DTEntry entry, int level)
{
DTEntryIterator entryIter;
DTEntryIterator entryIter;
PrintFlattenedNode(entry, level);
PrintFlattenedNode(entry, level);
if (kSuccess != DTCreateEntryIterator(entry, &entryIter)) {
printf("Couldn't create entry iterator\n");
return;
}
level++;
while (kSuccess == DTIterateEntries( entryIter, &entry )) {
_PrintFlattenedTree(entry, level);
}
DTDisposeEntryIterator(entryIter);
if (kSuccess != DTCreateEntryIterator(entry, &entryIter))
{
printf("Couldn't create entry iterator\n");
return;
}
level++;
while (kSuccess == DTIterateEntries( entryIter, &entry ))
{
_PrintFlattenedTree(entry, level);
}
DTDisposeEntryIterator(entryIter);
}
//==============================================================================
void
DT__PrintFlattenedTree(DTEntry entry)
{
_PrintFlattenedTree(entry, 0);
_PrintFlattenedTree(entry, 0);
}
//==============================================================================
int
main(int argc, char **argv)
{
DTEntry dtEntry;
DTPropertyIterator propIter;
DTEntryIterator entryIter;
void*prop;
intpropSize;
char*name;
void *flatTree;
uint32_t flatSize;
DTEntrydtEntry;
DTPropertyIteratorpropIter;
DTEntryIteratorentryIter;
void*prop;
intpropSize;
char*name;
void*flatTree;
uint32_tflatSize;
Node *node;
Node *node;
node = AddChild(NULL, "device-tree");
AddProperty(node, "potato", 4, "foo");
AddProperty(node, "chemistry", 4, "bar");
AddProperty(node, "physics", 4, "baz");
node = AddChild(NULL, "device-tree");
AddProperty(node, "potato", 4, "foo");
AddProperty(node, "chemistry", 4, "bar");
AddProperty(node, "physics", 4, "baz");
node = AddChild(node, "dev");
AddProperty(node, "one", 4, "one");
AddProperty(node, "two", 4, "two");
AddProperty(node, "three", 6, "three");
node = AddChild(node, "dev");
AddProperty(node, "one", 4, "one");
AddProperty(node, "two", 4, "two");
AddProperty(node, "three", 6, "three");
node = AddChild(rootNode, "foo");
AddProperty(node, "aaa", 4, "aab");
AddProperty(node, "bbb", 4, "bbc");
AddProperty(node, "cccc", 6, "ccccd");
node = AddChild(rootNode, "foo");
AddProperty(node, "aaa", 4, "aab");
AddProperty(node, "bbb", 4, "bbc");
AddProperty(node, "cccc", 6, "ccccd");
node = FindNode("/this/is/a/test", 1);
AddProperty(node, "dddd", 12, "abcdefghijk");
node = FindNode("/this/is/a/test", 1);
AddProperty(node, "dddd", 12, "abcdefghijk");
printf("In-memory tree:\n\n");
printf("In-memory tree:\n\n");
PrintTree(rootNode);
PrintTree(rootNode);
FlattenDeviceTree(&flatTree, &flatSize);
FlattenDeviceTree(&flatTree, &flatSize);
printf("Flat tree = %p, size %d\n", flatTree, flatSize);
printf("Flat tree = %p, size %d\n", flatTree, flatSize);
dtEntry = (DTEntry)flatTree;
dtEntry = (DTEntry)flatTree;
printf("\n\nPrinting flat tree\n\n");
printf("\n\nPrinting flat tree\n\n");
DTInit(dtEntry);
DTInit(dtEntry);
PrintFlattenedTree((DTEntry)flatTree);
PrintFlattenedTree((DTEntry)flatTree);
#if 0
printf("=== Entry %p ===\n", dtEntry);
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) {
printf("Couldn't create property iterator\n");
return 1;
printf("=== Entry %p ===\n", dtEntry);
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter))
{
printf("Couldn't create property iterator\n");
return 1;
}
while( kSuccess == DTIterateProperties( propIter, &name))
{
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
continue;
printf(" Property %s = %s\n", name, prop);
}
while( kSuccess == DTIterateProperties( propIter, &name)) {
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
continue;
printf(" Property %s = %s\n", name, prop);
}
DTDisposePropertyIterator(propIter);
printf("========\n");
DTDisposePropertyIterator(propIter);
printf("========\n");
if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter)) {
printf("Couldn't create entry iterator\n");
return 1;
}
while (kSuccess == DTIterateEntries( entryIter, &dtEntry )) {
printf("=== Entry %p ===\n", dtEntry);
if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter))
{
printf("Couldn't create entry iterator\n");
return 1;
}
while (kSuccess == DTIterateEntries( entryIter, &dtEntry ))
{
printf("=== Entry %p ===\n", dtEntry);
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) {
printf("Couldn't create property iterator\n");
return 1;
}
while( kSuccess == DTIterateProperties( propIter, &name)) {
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
continue;
printf(" Property %s = %s\n", name, prop);
}
DTDisposePropertyIterator(propIter);
printf("========\n");
}
DTDisposeEntryIterator(entryIter);
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter))
{
printf("Couldn't create property iterator\n");
return 1;
}
while( kSuccess == DTIterateProperties( propIter, &name))
{
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
continue;
printf(" Property %s = %s\n", name, prop);
}
DTDisposePropertyIterator(propIter);
printf("========\n");
}
DTDisposeEntryIterator(entryIter);
#endif
return 0;
return 0;
}
#endif
trunk/i386/libsaio/hfs.c
109109
110110
111111
112
113
112114
113115
114
115
116
117
116
117
118
119
118120
119121
122
123
124
120125
121126
122
123
124
127
128
129
130
125131
126132
133
134
135
127136
128137
129138
130139
131
132
140
141
133142
134
143
135144
136
137
145
146
147
138148
149
139150
140151
141152
153
154
155
142156
143157
144
145
158
159
146160
147
161
162
148163
149
164
150165
151
152
166
167
153168
154169
155
156
157
158
159
160
161
162
163
164
165
166
167
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
168196
169197
170
171
172
173
174
198
199
200
201
202
175203
176
177
178
204
205
206
179207
180
181
208
209
210
182211
183
184
185
186
187
188
212
213
214
215
216
217
218
189219
190
191
220
221
192222
193
194
195
196
197
198
223
224
225
226
227
199228
200
201
229
202230
203
204
205
206
207
231
232
233
234
235
236
208237
209
210
238
239
211240
212
213
241
242
214243
215
244
216245
217
218
219
246
247
248
220249
221
222
223
224
225
226
227
250
251
252
253
254
255
256
228257
229
230
231
232
258
259
260
261
233262
234263
235
236
237
238264
239
240
241
242
265
266
243267
244
245
268
269
270
271
246272
247
248
273
249274
250
251
252
253
254
275
255276
256
277
278
279
280
281
282
283
284
257285
258286
287
288
289
259290
260291
261
292
262293
263294
264295
......
267298
268299
269300
270
271
272
273
274
275
276
277
278
301
302
279303
280
281
282
283
284
304
285305
286
287
288
289
306
307
308
309
310
311
312
313
314
315
316
317
318
319
290320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
291339
292
293
294
340
341
342
343
344
345
295346
296347
297
298
299
300
348
349
350
351
352
301353
302
303
304
305
306
354
355
356
357
358
307359
308360
309361
......
10301082
10311083
10321084
1033
1085
10341086
10351087
1036
1088
10371089
1038
1039
1090
1091
10401092
10411093
10421094
u_int16_t *uniStr2, u_int32_t len2);
//==============================================================================
static void SwapFinderInfo(FndrFileInfo *dst, FndrFileInfo *src)
{
dst->fdType = SWAP_BE32(src->fdType);
dst->fdCreator = SWAP_BE32(src->fdCreator);
dst->fdFlags = SWAP_BE16(src->fdFlags);
// Don't bother with location
dst->fdType = SWAP_BE32(src->fdType);
dst->fdCreator = SWAP_BE32(src->fdCreator);
dst->fdFlags = SWAP_BE16(src->fdFlags);
// Don't bother with location
}
//==============================================================================
void HFSFree(CICell ih)
{
if(gCurrentIH == ih)
gCurrentIH = 0;
free(ih);
if(gCurrentIH == ih) {
gCurrentIH = 0;
}
free(ih);
}
//==============================================================================
bool HFSProbe (const void *buf)
{
const HFSMasterDirectoryBlock *mdb;
const HFSPlusVolumeHeader *header;
mdb=(const HFSMasterDirectoryBlock *)(((const char*)buf)+kMDBBaseOffset);
header=(const HFSPlusVolumeHeader *)(((const char*)buf)+kMDBBaseOffset);
mdb = (const HFSMasterDirectoryBlock *)(((const char*)buf)+kMDBBaseOffset);
header = (const HFSPlusVolumeHeader *)(((const char*)buf)+kMDBBaseOffset);
if ( SWAP_BE16(mdb->drSigWord) == kHFSSigWord )
if ( SWAP_BE16(mdb->drSigWord) == kHFSSigWord ) {
return true;
if (SWAP_BE16(header->signature) != kHFSPlusSigWord &&
SWAP_BE16(header->signature) != kHFSXSigWord)
}
if (SWAP_BE16(header->signature) != kHFSPlusSigWord && SWAP_BE16(header->signature) != kHFSXSigWord) {
return false;
}
return true;
}
//==============================================================================
long HFSInitPartition(CICell ih)
{
long extentSize, extentFile, nodeSize;
void *extent;
long extentSize, extentFile, nodeSize;
void *extent;
if (ih == gCurrentIH) {
if (ih == gCurrentIH)
{
#ifdef __i386__
CacheInit(ih, gCacheBlockSize);
CacheInit(ih, gCacheBlockSize);
#endif
return 0;
}
return 0;
}
#ifdef __i386__
if (!gTempStr) gTempStr = (char *)malloc(4096);
if (!gLinkTemp) gLinkTemp = (char *)malloc(64);
if (!gBTreeHeaderBuffer) gBTreeHeaderBuffer = (char *)malloc(512);
if (!gHFSMdbVib) {
gHFSMdbVib = (char *)malloc(kBlockSize);
gHFSMDB = (HFSMasterDirectoryBlock *)gHFSMdbVib;
}
if (!gHFSPlusHeader) {
gHFSPlusHeader = (char *)malloc(kBlockSize);
gHFSPlus = (HFSPlusVolumeHeader *)gHFSPlusHeader;
}
if (!gTempStr || !gLinkTemp || !gBTreeHeaderBuffer ||
!gHFSMdbVib || !gHFSPlusHeader) return -1;
if (!gTempStr)
{
gTempStr = (char *)malloc(4096);
}
if (!gLinkTemp)
{
gLinkTemp = (char *)malloc(64);
}
if (!gBTreeHeaderBuffer)
{
gBTreeHeaderBuffer = (char *)malloc(512);
}
if (!gHFSMdbVib)
{
gHFSMdbVib = (char *)malloc(kBlockSize);
gHFSMDB = (HFSMasterDirectoryBlock *)gHFSMdbVib;
}
if (!gHFSPlusHeader)
{
gHFSPlusHeader = (char *)malloc(kBlockSize);
gHFSPlus = (HFSPlusVolumeHeader *)gHFSPlusHeader;
}
if (!gTempStr || !gLinkTemp || !gBTreeHeaderBuffer || !gHFSMdbVib || !gHFSPlusHeader)
{
return -1;
}
#endif /* __i386__ */
gAllocationOffset = 0;
gIsHFSPlus = 0;
gCaseSensitive = 0;
gBTHeaders[0] = 0;
gBTHeaders[1] = 0;
gAllocationOffset = 0;
gIsHFSPlus = 0;
gCaseSensitive = 0;
gBTHeaders[0] = 0;
gBTHeaders[1] = 0;
// Look for the HFS MDB
Seek(ih, kMDBBaseOffset);
Read(ih, (long)gHFSMdbVib, kBlockSize);
// Look for the HFS MDB
Seek(ih, kMDBBaseOffset);
Read(ih, (long)gHFSMdbVib, kBlockSize);
if ( SWAP_BE16(gHFSMDB->drSigWord) == kHFSSigWord ) {
gAllocationOffset = SWAP_BE16(gHFSMDB->drAlBlSt) * kBlockSize;
if (SWAP_BE16(gHFSMDB->drSigWord) == kHFSSigWord)
{
gAllocationOffset = SWAP_BE16(gHFSMDB->drAlBlSt) * kBlockSize;
// See if it is HFSPlus
if (SWAP_BE16(gHFSMDB->drEmbedSigWord) != kHFSPlusSigWord) {
// Normal HFS;
gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSMDB->drAlBlkSiz);
CacheInit(ih, gCacheBlockSize);
gCurrentIH = ih;
// See if it is HFSPlus
if (SWAP_BE16(gHFSMDB->drEmbedSigWord) != kHFSPlusSigWord)
{
// Normal HFS;
gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSMDB->drAlBlkSiz);
CacheInit(ih, gCacheBlockSize);
gCurrentIH = ih;
// grab the 64 bit volume ID
bcopy(&gHFSMDB->drFndrInfo[6], &gVolID, 8);
// grab the 64 bit volume ID
bcopy(&gHFSMDB->drFndrInfo[6], &gVolID, 8);
// Get the Catalog BTree node size.
extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
extentFile = kHFSCatalogFileID;
ReadExtent(extent, extentSize, extentFile, 0, 256,
gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
// Get the Catalog BTree node size.
extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
extentFile = kHFSCatalogFileID;
ReadExtent(extent, extentSize, extentFile, 0, 256, gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 +
sizeof(BTNodeDescriptor)))->nodeSize);
nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + sizeof(BTNodeDescriptor)))->nodeSize);
// If the BTree node size is larger than the block size, reset the cache.
if (nodeSize > gBlockSize) {
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
// If the BTree node size is larger than the block size, reset the cache.
if (nodeSize > gBlockSize)
{
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
return 0;
}
return 0;
}
// Calculate the offset to the embeded HFSPlus volume.
gAllocationOffset += (long long)SWAP_BE16(gHFSMDB->drEmbedExtent.startBlock) *
// Calculate the offset to the embeded HFSPlus volume.
gAllocationOffset += (long long)SWAP_BE16(gHFSMDB->drEmbedExtent.startBlock) *
SWAP_BE32(gHFSMDB->drAlBlkSiz);
}
}
// Look for the HFSPlus Header
Seek(ih, gAllocationOffset + kMDBBaseOffset);
Read(ih, (long)gHFSPlusHeader, kBlockSize);
// Look for the HFSPlus Header
Seek(ih, gAllocationOffset + kMDBBaseOffset);
Read(ih, (long)gHFSPlusHeader, kBlockSize);
// Not a HFS+ or HFSX volume.
if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord &&
SWAP_BE16(gHFSPlus->signature) != kHFSXSigWord) {
verbose("HFS signature was not present.\n");
gCurrentIH = 0;
return -1;
}
// Not a HFS+ or HFSX volume.
if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord && SWAP_BE16(gHFSPlus->signature) != kHFSXSigWord)
{
verbose("HFS signature was not present.\n");
gCurrentIH = 0;
return -1;
}
gIsHFSPlus = 1;
gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSPlus->blockSize);
CacheInit(ih, gCacheBlockSize);
gCurrentIH = ih;
gIsHFSPlus = 1;
gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSPlus->blockSize);
CacheInit(ih, gCacheBlockSize);
gCurrentIH = ih;
ih->modTime = SWAP_BE32(gHFSPlus->modifyDate) - 2082844800;
// grab the 64 bit volume ID
bcopy(&gHFSPlus->finderInfo[24], &gVolID, 8);
// Get the Catalog BTree node size.
extent = &gHFSPlus->catalogFile.extents;
extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
extentFile = kHFSCatalogFileID;
// grab the 64 bit volume ID
bcopy(&gHFSPlus->finderInfo[24], &gVolID, 8);
ReadExtent(extent, extentSize, extentFile, 0, 256,
gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
// Get the Catalog BTree node size.
extent = &gHFSPlus->catalogFile.extents;
extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
extentFile = kHFSCatalogFileID;
nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 +
sizeof(BTNodeDescriptor)))->nodeSize);
ReadExtent(extent, extentSize, extentFile, 0, 256, gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
// If the BTree node size is larger than the block size, reset the cache.
if (nodeSize > gBlockSize) {
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + sizeof(BTNodeDescriptor)))->nodeSize);
return 0;
// If the BTree node size is larger than the block size, reset the cache.
if (nodeSize > gBlockSize)
{
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
return 0;
}
//==============================================================================
long HFSLoadFile(CICell ih, char * filePath)
{
return HFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0);
return HFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0);
}
long HFSReadFile(CICell ih, char * filePath, void *base, uint64_t offset, uint64_t length)
char devStr[12];
long dirID, result, flags;
if (HFSInitPartition(ih) == -1) return -1;
dirID = kHFSRootFolderID;
// Skip a lead '\'. Start in the system folder if there are two.
if (filePath[0] == '/') {
if (filePath[1] == '/') {
if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
if (dirID == 0) {
if (HFSInitPartition(ih) == -1)
{
return -1;
}
filePath++;
}
filePath++;
}
}
result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0);
if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
return -1;
}
dirID = kHFSRootFolderID;
// Skip a lead '\'. Start in the system folder if there are two.
if (filePath[0] == '/')
{
if (filePath[1] == '/')
{
if (gIsHFSPlus)
{
dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
}
else
{
dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
}
if (dirID == 0)
{
return -1;
}
filePath++;
}
filePath++;
}
result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0);
if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat))
{
return -1;
}
#if UNUSED
// Not yet for Intel. System.config/Default.table will fail this check.
// Check file owner and permissions.
if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite)) return -1;
// Not yet for Intel. System.config/Default.table will fail this check.
// Check file owner and permissions.
if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite))
{
return -1;
}
#endif
result = ReadFile(entry, &length, base, offset);
if (result == -1) {
return -1;
}
result = ReadFile(entry, &length, base, offset);
if (result == -1)
{
return -1;
}
getDeviceDescription(ih, devStr);
verbose("Read HFS%s file: [%s/%s] %d bytes.\n",
(gIsHFSPlus ? "+" : ""), devStr, filePath, (uint32_t)length);
return length;
getDeviceDescription(ih, devStr);
verbose("Read HFS%s file: [%s/%s] %d bytes.\n",
(gIsHFSPlus ? "+" : ""), devStr, filePath, (uint32_t)length);
return length;
}
long HFSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name,
{
HFSPlusExtentKey *searchKey, *trialKey;
long result;
searchKey = key;
trialKey = testKey;
// assume searchKey < trialKey
result = -1;
result = -1;
if (searchKey->fileID == trialKey->fileID) {
// FileNum's are equal; compare fork types
if (searchKey->forkType == trialKey->forkType) {
trunk/i386/libsaio/acpi_patcher.c
103103
104104
105105
106
107
108
109
110
106
107
108
109
111110
112
113
114
115
116
117
118
111
112
113
114
115
116
119117
120118
121119
......
273271
274272
275273
276
274
277275
278
279
280
276
277
278
281279
282280
283
281
284282
285283
286284
......
288286
289287
290288
291
292
293
289
290
291
294292
295293
296294
......
303301
304302
305303
306
307
308
304
305
306
309307
310308
311309
......
317315
318316
319317
320
321
322
318
319
320
323321
324322
325323
......
330328
331329
332330
333
334
331
332
335333
336334
337335
......
340338
341339
342340
343
344
341
342
345343
346344
347345
......
351349
352350
353351
354
355
352
353
356354
357355
358356
......
361359
362360
363361
364
365
362
363
366364
367365
368366
......
370368
371369
372370
373
374
371
372
375373
376374
377375
......
638636
639637
640638
641
639
642640
643641
644
645
646
642
643
644
647645
648646
649647
650
648
651649
652650
653651
......
862860
863861
864862
865
863
866864
867865
868866
869867
868
870869
871870
872871
......
894893
895894
896895
897
896
898897
899898
900899
901
900
902901
903902
904903
......
912911
913912
914913
915
914
916915
917916
918917
......
974973
975974
976975
976
977977
978978
979979
980980
981981
982982
983
983
984984
985985
986986
......
10941094
10951095
10961096
1097
10971098
10981099
10991100
......
11601161
11611162
11621163
1163
1164
11641165
11651166
11661167
// Start searching any potential location for ACPI Table
snprintf(dirSpec, sizeof(dirSpec), "%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
{
snprintf(dirSpec, sizeof(dirSpec), "/Extra/%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
if (fd < 0) {
snprintf(dirSpec, sizeof(dirSpec), "/Extra/%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
{
snprintf(dirSpec, sizeof(dirSpec), "bt(0,0)/Extra/%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
{
// NOT FOUND:
verbose("ACPI Table not found: %s\n", filename);
*dirSpec = '\0';
snprintf(dirSpec, sizeof(dirSpec), "bt(0,0)/Extra/%s", filename);
fd = open(dirSpec, 0);
if (fd < 0) {
// NOT FOUND:
verbose("ACPI Table not found: %s\n", filename);
*dirSpec = '\0';
}
}
}
unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + (c3_enabled ? 1 : 0);
struct aml_chunk* root = aml_create_node(NULL);
AML_CHUNK* root = aml_create_node(NULL);
aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header
struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");
struct aml_chunk* name = aml_add_name(scop, "CST_");
struct aml_chunk* pack = aml_add_package(name);
AML_CHUNK* scop = aml_add_scope(root, "\\_PR_");
AML_CHUNK* name = aml_add_name(scop, "CST_");
AML_CHUNK* pack = aml_add_package(name);
aml_add_byte(pack, cstates_count);
struct aml_chunk* tmpl = aml_add_package(pack);
AML_CHUNK* tmpl = aml_add_package(pack);
if (cst_using_systemio)
{
// C1
resource_template_register_fixedhw[9] = 0x00;
resource_template_register_fixedhw[18] = 0x00;
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x01); // C1
aml_add_word(tmpl, 0x0001); // Latency
aml_add_dword(tmpl, 0x000003e8); // Power
aml_add_byte(tmpl, 0x01);// C1
aml_add_word(tmpl, 0x0001);// Latency
aml_add_dword(tmpl, 0x000003e8);// Power
uint8_t p_blk_lo, p_blk_hi;
resource_template_register_systemio[11] = p_blk_lo; // C2
resource_template_register_systemio[12] = p_blk_hi; // C2
aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
aml_add_byte(tmpl, 0x02); // C2
aml_add_word(tmpl, 0x0040); // Latency
aml_add_dword(tmpl, 0x000001f4); // Power
aml_add_byte(tmpl, 0x02);// C2
aml_add_word(tmpl, 0x0040);// Latency
aml_add_dword(tmpl, 0x000001f4);// Power
}
if (c4_enabled) // C4
resource_template_register_systemio[11] = p_blk_lo; // C4
resource_template_register_systemio[12] = p_blk_hi; // C4
aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
aml_add_byte(tmpl, 0x04); // C4
aml_add_word(tmpl, 0x0080); // Latency
aml_add_dword(tmpl, 0x000000C8); // Power
aml_add_byte(tmpl, 0x04);// C4
aml_add_word(tmpl, 0x0080);// Latency
aml_add_dword(tmpl, 0x000000C8);// Power
}
else if (c3_enabled) // C3
{
resource_template_register_systemio[11] = p_blk_lo; // C3
resource_template_register_systemio[12] = p_blk_hi; // C3
aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
aml_add_byte(tmpl, 0x03);// C3
aml_add_word(tmpl, 0x0060);// Latency
aml_add_byte(tmpl, 0x03);// C3
aml_add_word(tmpl, 0x0060);// Latency
aml_add_dword(tmpl, 0x0000015e);// Power
}
}
// C1
resource_template_register_fixedhw[11] = 0x00; // C1
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x01);// C1
aml_add_word(tmpl, 0x0001);// Latency
aml_add_byte(tmpl, 0x01);// C1
aml_add_word(tmpl, 0x0001);// Latency
aml_add_dword(tmpl, 0x000003e8);// Power
resource_template_register_fixedhw[18] = 0x03;
tmpl = aml_add_package(pack);
resource_template_register_fixedhw[11] = 0x10; // C2
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x02);// C2
aml_add_word(tmpl, 0x0040);// Latency
aml_add_byte(tmpl, 0x02);// C2
aml_add_word(tmpl, 0x0040);// Latency
aml_add_dword(tmpl, 0x000001f4);// Power
}
tmpl = aml_add_package(pack);
resource_template_register_fixedhw[11] = 0x30; // C4
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x04);// C4
aml_add_word(tmpl, 0x0080);// Latency
aml_add_byte(tmpl, 0x04);// C4
aml_add_word(tmpl, 0x0080);// Latency
aml_add_dword(tmpl, 0x000000C8);// Power
}
else if (c3_enabled)
tmpl = aml_add_package(pack);
resource_template_register_fixedhw[11] = 0x20; // C3
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x03);// C3
aml_add_word(tmpl, 0x0060);// Latency
aml_add_byte(tmpl, 0x03);// C3
aml_add_word(tmpl, 0x0060);// Latency
aml_add_dword(tmpl, 0x0000015e);// Power
}
}
{
int i;
struct aml_chunk* root = aml_create_node(NULL);
AML_CHUNK* root = aml_create_node(NULL);
aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header
struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");
struct aml_chunk* name = aml_add_name(scop, "PSS_");
struct aml_chunk* pack = aml_add_package(name);
AML_CHUNK* scop = aml_add_scope(root, "\\_PR_");
AML_CHUNK* name = aml_add_name(scop, "PSS_");
AML_CHUNK* pack = aml_add_package(name);
for (i = 0; i < p_states_count; i++)
{
struct aml_chunk* pstt = aml_add_package(pack);
AML_CHUNK* pstt = aml_add_package(pack);
aml_add_dword(pstt, p_states[i].Frequency);
aml_add_dword(pstt, 0x00000000); // Power
/* Try using the file specified with the DSDT option */
if (getValueForKey(kDSDT, &filename, &len, &bootInfo->chameleonConfig))
{
snprintf(dirSpec, sizeof(dirSpec), filename);
snprintf(dirSpec, sizeof(dirSpec), filename);
}
else
{
sprintf(dirSpec, "DSDT.aml");
//verbose("dirSpec, DSDT.aml");
}
// Load replacement DSDT
{
int i;
for (i=0; i<30; i++)
for (i = 0; i < 30; i++)
{
char filename[512];
sprintf(filename, i>0?"SSDT-%d.aml":"SSDT.aml", i);
sprintf(filename, i > 0?"SSDT-%d.aml":"SSDT.aml", i);
if ( (new_ssdt[ssdt_count] = loadACPITable(filename)) )
{
}
// Do the same procedure for both versions of ACPI
for (version=0; version<2; version++) {
for (version = 0; version < 2; version++) {
struct acpi_2_rsdp *rsdp, *rsdp_mod;
struct acpi_2_rsdt *rsdt, *rsdt_mod;
int rsdplength;
if (drop_ssdt && tableSign(table, "SSDT"))
{
verbose("OEM SSDT tables was dropped\n");
dropoffset++;
continue;
}
if (tableSign(table, "DSDT"))
{
DBG("DSDT found\n");
verbose("Custom DSDT table was found\n");
if(new_dsdt)
{
rsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;
if (drop_ssdt && tableSign(table, "SSDT"))
{
verbose("OEM SSDT tables was dropped\n");
dropoffset++;
continue;
}
xsdt_entries=(uint64_t *)(xsdt_mod+1);
// Mozodojo: Insert additional SSDTs into XSDT
if(ssdt_count>0)
if(ssdt_count > 0)
{
int j;
trunk/i386/libsaio/device_tree.h
11
2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
323
424
525
......
828
929
1030
31
32
33
1134
12
13
14
15
16
35
36
37
38
1739
1840
41
42
43
1944
20
21
22
23
24
25
45
46
47
48
2649
2750
2851
......
4770
4871
4972
50
51
52
53
73
74
75
5476
5577
5678
/*
* Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved.
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef __DEVICE_TREE_H
#include <stdbool.h>
#include <stdint.h>
//==============================================================================
typedef struct _Property {
const char * name;
uint32_t length;
void * value;
struct _Property * next;
const char *name;
uint32_tlength;
void *value;
struct _Property *next;
} Property;
//==============================================================================
typedef struct _Node {
struct _Property * properties;
struct _Property * last_prop;
struct _Node * children;
struct _Node * next;
struct _Property *properties;
struct _Property *last_prop;
struct _Node *children;
struct _Node *next;
} Node;
void
DT__Initialize(void);
/*
* Free up memory used by in-memory representation
* of device tree.
*/
// Free up memory used by in-memory representation of device tree.
extern void
DT__Finalize(void);
trunk/i386/libsaio/allocate.c
3333
3434
3535
36
37
3638
3739
3840
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
5864
5965
66
67
68
6069
61
70
6271
63
72
6473
65
66
67
68
69
70
74
75
76
77
78
7179
72
73
74
75
76
80
81
82
7783
78
84
85
86
7987
#define RoundPage(x) ((((unsigned)(x)) + kPageSize - 1) & ~(kPageSize - 1))
//==============================================================================
long
AllocateMemoryRange(char * rangeName, long start, long length, long type)
{
char *nameBuf;
uint32_t *buffer;
nameBuf = malloc(strlen(rangeName) + 1);
if (nameBuf == 0) return -1;
buffer = malloc(2 * sizeof(uint32_t));
if (buffer == 0) {
free(nameBuf);
return -1;
}
strcpy(nameBuf, rangeName);
buffer[0] = start;
buffer[1] = length;
DT__AddProperty(gMemoryMapNode, nameBuf, 2 * sizeof(uint32_t), (char *)buffer);
return 0;
char *nameBuf;
uint32_t *buffer;
nameBuf = malloc(strlen(rangeName) + 1);
if (nameBuf == 0) {
return -1;
}
buffer = malloc(2 * sizeof(uint32_t));
if (buffer == 0) {
free(nameBuf);
return -1;
}
strcpy(nameBuf, rangeName);
buffer[0] = start;
buffer[1] = length;
DT__AddProperty(gMemoryMapNode, nameBuf, 2 * sizeof(uint32_t), (char *)buffer);
return 0;
}
//==============================================================================
long
AllocateKernelMemory( long inSize )
AllocateKernelMemory(long inSize)
{
long addr;
long addr;
if (gImageLastKernelAddr == 0) {
gImageLastKernelAddr = RoundPage( bootArgs->kaddr +
bootArgs->ksize );
}
addr = gImageLastKernelAddr;
gImageLastKernelAddr += RoundPage(inSize);
if (gImageLastKernelAddr == 0) {
gImageLastKernelAddr = RoundPage(bootArgs->kaddr + bootArgs->ksize);
}
addr = gImageLastKernelAddr;
gImageLastKernelAddr += RoundPage(inSize);
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) ) {
stop ("AllocateKernelMemory error");
}
bootArgs->ksize = gImageLastKernelAddr - bootArgs->kaddr;
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) ) {
stop ("AllocateKernelMemory error");
}
return addr;
bootArgs->ksize = gImageLastKernelAddr - bootArgs->kaddr;
return addr;
}
trunk/i386/libsaio/bootargs.h
4545
4646
4747
48
49
48
49
5050
5151
5252
......
5757
5858
5959
60
60
6161
6262
6363
......
9393
9494
9595
96
97
96
97
9898
9999
100100
101101
102102
103
104
103
104
105105
106106
107107
......
109109
110110
111111
112
113
112
113
114114
115115
116116
117117
118
118
119119
120120
121121
122
122
123123
124
124
125125
126126
127127
128128
129
129
130130
131
131
132132
133133
134
134
135135
136136
137
137
138138
139139
140140
141
141
142142
143143
144
144
145145
146146
147
147
148148
149149
150150
......
152152
153153
154154
155
155
156156
157157
158158
159159
160160
161
161
162162
163
163
164164
165165
166166
167167
168
168
169169
170
170
171171
172172
173
173
174174
175175
176
176
177177
178178
179179
180
180
181181
182182
183183
......
185185
186186
187187
188
188
189189
190190
191191
enum {
kEfiReservedMemoryType= 0,
kEfiLoaderCode= 1,
kEfiLoaderData= 2,
kEfiLoaderCode= 1,
kEfiLoaderData= 2,
kEfiBootServicesCode= 3,
kEfiBootServicesData= 4,
kEfiRuntimeServicesCode= 5,
kEfiACPIMemoryNVS= 10,
kEfiMemoryMappedIO= 11,
kEfiMemoryMappedIOPortSpace = 12,
kEfiPalCode= 13,
kEfiPalCode= 13,
kEfiMaxMemoryType= 14
};
/* Values for v_display */
#define GRAPHICS_MODE1
#define FB_TEXT_MODE2
#define GRAPHICS_MODE1
#define FB_TEXT_MODE2
/* Boot argument structure - passed into Mach kernel at boot time.
* "Revision" can be incremented for compatible changes
*/
// Lion
#define kBootArgsRevision0
#define kBootArgsVersion2
#define kBootArgsRevision0
#define kBootArgsVersion2
// Snow Leopard and older
#define kBootArgsPreLionRevision6
/* Snapshot constants of previous revisions that are supported */
#define kBootArgsEfiMode3232
#define kBootArgsEfiMode6464
#define kBootArgsEfiMode3232
#define kBootArgsEfiMode6464
typedef struct boot_args {
uint16_t Revision;/* Revision of boot_args structure */
uint16_t Version;/* Version of boot_args structure */
uint8_t efiMode; /* 32 = 32-bit, 64 = 64-bit */
uint8_t debugMode; /* Bit field with behavior changes */
uint8_t __reserved1[2];
char CommandLine[BOOT_LINE_LENGTH];/* Passed in command line */
uint32_t MemoryMap; /* Physical address of memory map */
uint32_t MemoryMapSize;
uint32_t MemoryMapDescriptorSize;
uint32_t MemoryMapDescriptorVersion;
Boot_VideoVideo;/* Video Information */
uint32_t deviceTreeP; /* Physical address of flattened device tree */
uint32_t deviceTreeLength; /* Length of flattened tree */
uint32_t kaddr; /* Physical address of beginning of kernel text */
uint32_t ksize; /* Size of combined kernel text+data+efi */
uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */
uint32_t efiRuntimeServicesPageCount;
uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */
uint32_t efiSystemTable; /* physical address of system table in runtime area */
uint32_t __reserved2;
uint32_t performanceDataStart; /* physical address of log */
uint32_t performanceDataSize;
uint32_t keyStoreDataStart; /* physical address of key store data */
uint32_t keyStoreDataSize;
uint64_tbootMemStart;
uint64_t PhysicalMemorySize;
uint64_t FSBFrequency;
uint32_t __reserved4[734];
} boot_args;
typedef struct boot_args_pre_lion {
uint16_t Revision;/* Revision of boot_args structure */
uint16_t Version;/* Version of boot_args structure */
char CommandLine[BOOT_LINE_LENGTH];/* Passed in command line */
uint32_t MemoryMap; /* Physical address of memory map */
uint32_t MemoryMapSize;
uint32_t MemoryMapDescriptorSize;
uint32_t MemoryMapDescriptorVersion;
Boot_VideoVideo;/* Video Information */
uint32_t deviceTreeP; /* Physical address of flattened device tree */
uint32_t deviceTreeLength; /* Length of flattened tree */
uint32_t kaddr; /* Physical address of beginning of kernel text */
uint32_t ksize; /* Size of combined kernel text+data+efi */
uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */
uint32_t efiRuntimeServicesPageCount;
uint32_t efiSystemTable; /* physical address of system table in runtime area */
uint8_t efiMode; /* 32 = 32-bit, 64 = 64-bit */
uint8_t __reserved1[3];
uint32_t __reserved2[1];
uint32_t performanceDataSize;
uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */
uint32_t __reserved3[2];
} boot_args_pre_lion;
extern char gMacOSVersion[8];
trunk/i386/libsaio/spd.c
6969
7070
7171
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
10972
11073
11174
......
11982
12083
12184
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
122128
123129
124130
......
132138
133139
134140
135
136
137
138
141
142
143
144
139145
140
141
142
143
144
145
146
147
148
149
150
151
146
147
148
149
150
151
152
153
154
152155
153
154
155
156
157
158
159
160
161
162
163
164
165
166
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
167189
168190
169
191
170192
171193
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
199227
200228
201229
202230
203231
204
232
205233
206234
207
235
208236
209
210
211
212
213
214
215
216
237
238
239
240
241
242
243
244
245
246
217247
218
248
219249
220250
221
251
222252
223253
224254
225255
226256
227
257
258
228259
229260
230
261
262
231263
232264
233265
234
235
266
267
236268
237
269
270
238271
239272
240
273
274
275
241276
277
242278
279
243280
281
244282
245283
246284
......
249287
250288
251289
252
290
253291
254292
255
256
257
258
259
293
294
295
296
297
260298
261299
262300
263301
264302
265303
266
304
267305
268
269
306
307
270308
271
272
309
310
273311
274
312
275313
276314
277
278
279
280
281
282
283
284
315
316
317
318
319
320
321
322
323
324
285325
286326
287
327
328
288329
289
290
291
292
330
331
332
333
293334
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
335
317336
318
319
320
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
321378
322379
323
380
381
324382
325383
326384
327
385
386
328387
329388
330389
......
342401
343402
344403
345
346
404
405
406
347407
348
349
350
351
352
353
354
355
356
408
409
410
411
357412
358413
359
414
360415
361416
362417
418
363419
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
381445
382446
383447
......
385449
386450
387451
388
389
452
453
390454
391
455
456
392457
393
394
395
396
458
459
460
461
397462
398
399
400
401
402
403
404
405
406
407
408
409
410
463
464
465
466
467
468
469
470
471
472
473
474
411475
412476
413477
414478
415
479
416480
417481
#define SMBHSTDAT 5
#define SBMBLKDAT 7
/** Read one byte from the intel i2c, used for reading SPD on intel chipsets only. */
unsigned char smb_read_byte_intel(uint32_t base, uint8_t adr, uint8_t cmd)
{
int l1, h1, l2, h2;
unsigned long long t;
outb(base + SMBHSTSTS, 0x1f);// reset SMBus Controller
outb(base + SMBHSTDAT, 0xff);
rdtsc(l1, h1);
while ( inb(base + SMBHSTSTS) & 0x01) // wait until read
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 100);
if (t > 5)
return 0xFF; // break
}
outb(base + SMBHSTCMD, cmd);
outb(base + SMBHSTADD, (adr << 1) | 0x01 );
outb(base + SMBHSTCNT, 0x48 );
rdtsc(l1, h1);
while (!( inb(base + SMBHSTSTS) & 0x02))// wait til command finished
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 100);
if (t > 5)
break;// break after 5ms
}
return inb(base + SMBHSTDAT);
}
/* SPD i2c read optimization: prefetch only what we need, read non prefetcheable bytes on the fly */
#define READ_SPD(spd, base, slot, x) spd[x] = smb_read_byte_intel(base, 0x50 + slot, x)
int spd_indexes[] = {
SPD_MEMORY_TYPE,
SPD_DDR3_MEMORY_BANK,
};
#define SPD_INDEXES_SIZE (sizeof(spd_indexes) / sizeof(int))
/** Read one byte from the intel i2c, used for reading SPD on intel chipsets only. */
unsigned char smb_read_byte_intel(uint32_t base, uint8_t adr, uint8_t cmd)
{
int l1, h1, l2, h2;
unsigned long long t;
outb(base + SMBHSTSTS, 0x1f);// reset SMBus Controller
outb(base + SMBHSTDAT, 0xff);
rdtsc(l1, h1);
while ( inb(base + SMBHSTSTS) & 0x01) // wait until read
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 100);
if (t > 5)
{
return 0xFF;// break
}
}
outb(base + SMBHSTCMD, cmd);
outb(base + SMBHSTADD, (adr << 1) | 0x01 );
outb(base + SMBHSTCNT, 0x48 );
rdtsc(l1, h1);
while (!( inb(base + SMBHSTSTS) & 0x02))// wait til command finished
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 100);
if (t > 5)
{
break;// break after 5ms
}
}
return inb(base + SMBHSTDAT);
}
/* SPD i2c read optimization: prefetch only what we need, read non prefetcheable bytes on the fly */
#define READ_SPD(spd, base, slot, x) spd[x] = smb_read_byte_intel(base, 0x50 + slot, x)
/** Read from spd *used* values only*/
static void init_spd(char * spd, uint32_t base, int slot)
{
have different formats, always return a valid ptr.*/
const char * getVendorName(RamSlotInfo_t* slot, uint32_t base, int slot_num)
{
uint8_t bank = 0;
uint8_t code = 0;
int i = 0;
uint8_t * spd = (uint8_t *) slot->spd;
uint8_t bank = 0;
uint8_t code = 0;
int i = 0;
uint8_t * spd = (uint8_t *) slot->spd;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { // DDR3
bank = (spd[SPD_DDR3_MEMORY_BANK] & 0x07f); // constructors like Patriot use b7=1
code = spd[SPD_DDR3_MEMORY_CODE];
for (i=0; i < VEN_MAP_SIZE; i++)
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
return vendorMap[i].name;
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
if(spd[64]==0x7f) {
for (i=64; i<72 && spd[i]==0x7f;i++) {
bank++;
READ_SPD(spd, base, slot_num,i+1); // prefetch next spd byte to read for next loop
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
{ // DDR3
bank = (spd[SPD_DDR3_MEMORY_BANK] & 0x07f); // constructors like Patriot use b7=1
code = spd[SPD_DDR3_MEMORY_CODE];
for (i=0; i < VEN_MAP_SIZE; i++)
{
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
{
return vendorMap[i].name;
}
READ_SPD(spd, base, slot_num,i);
code = spd[i];
} else {
code = spd[64];
bank = 0;
}
for (i=0; i < VEN_MAP_SIZE; i++)
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
return vendorMap[i].name;
}
/* OK there is no vendor id here lets try to match the partnum if it exists */
if (strstr(slot->PartNo,"GU332") == slot->PartNo) // Unifosa fingerprint
return "Unifosa";
return "NoName";
}
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR)
{
if(spd[64]==0x7f)
{
for (i=64; i<72 && spd[i]==0x7f;i++)
{
bank++;
READ_SPD(spd, base, slot_num, (uint8_t)(i+1)); // prefetch next spd byte to read for next loop
}
READ_SPD(spd, base, slot_num,(uint8_t)i);
code = spd[i];
}
else
{
code = spd[64];
bank = 0;
}
for (i=0; i < VEN_MAP_SIZE; i++)
{
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
{
return vendorMap[i].name;
}
}
}
/* OK there is no vendor id here lets try to match the partnum if it exists */
if (strstr(slot->PartNo,"GU332") == slot->PartNo) // Unifosa fingerprint
{
return "Unifosa";
}
return "NoName";
}
/** Get Default Memory Module Speed (no overclocking handled) */
/* Get Default Memory Module Speed (no overclocking handled) */
int getDDRspeedMhz(const char * spd)
{
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {
switch(spd[12]) {
case 0x0f:
return 1066;
case 0x0c:
return 1333;
case 0x0a:
return 1600;
case 0x14:
default:
return 800;
}
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
switch(spd[9]) {
case 0x50:
return 400;
case 0x3d:
return 533;
case 0x30:
return 667;
case 0x25:
default:
return 800;
}
}
return 800; // default freq for unknown types
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
{
switch(spd[12])
{
case 0x0f:
return 1066;
case 0x0c:
return 1333;
case 0x0a:
return 1600;
case 0x14:
default:
return 800;
}
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR)
{
switch(spd[9])
{
case 0x50:
return 400;
case 0x3d:
return 533;
case 0x30:
return 667;
case 0x25:
default:
return 800;
case 0x1E:
return 1066;
}
}
return 800; // default freq for unknown types
}
#define SMST(a) ((uint8_t)((spd[a] & 0xf0) >> 4))
#define SLST(a) ((uint8_t)(spd[a] & 0x0f))
/** Get DDR3 or DDR2 serial number, 0 most of the times, always return a valid ptr */
/* Get DDR3 or DDR2 serial number, 0 most of the times, always return a valid ptr */
const char *getDDRSerial(const char* spd)
{
static char asciiSerial[16];
static char asciiSerial[16];
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) // DDR3
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(122) /*& 0x7*/, SLST(122), SMST(123), SLST(123), SMST(124), SLST(124), SMST(125), SLST(125));
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) // DDR2 or DDR
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(95) /*& 0x7*/, SLST(95), SMST(96), SLST(96), SMST(97), SLST(97), SMST(98), SLST(98));
}
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) // DDR3
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(122) /*& 0x7*/, SLST(122), SMST(123), SLST(123), SMST(124), SLST(124), SMST(125), SLST(125));
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR) // DDR2 or DDR
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(95) /*& 0x7*/, SLST(95), SMST(96), SLST(96), SMST(97), SLST(97), SMST(98), SLST(98));
} else {
sprintf(asciiSerial, "0000000000000000");
}
return strdup(asciiSerial);
return strdup(asciiSerial);
}
/** Get DDR3 or DDR2 Part Number, always return a valid ptr */
/* Get DDR3 or DDR2 Part Number, always return a valid ptr */
const char * getDDRPartNum(char* spd, uint32_t base, int slot)
{
static char asciiPartNo[32];
int i, start=0, index = 0;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
{
start = 128;
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR)
{
start = 73;
}
// Check that the spd part name is zero terminated and that it is ascii:
bzero(asciiPartNo, sizeof(asciiPartNo));
// Check that the spd part name is zero terminated and that it is ascii:
bzero(asciiPartNo, sizeof(asciiPartNo));
char c;
for (i=start; i < start + sizeof(asciiPartNo); i++) {
for (i=start; i < start + sizeof(asciiPartNo); i++)
{
READ_SPD(spd, base, slot, i); // only read once the corresponding model part (ddr3 or ddr2)
c = spd[i];
if (isalpha(c) || isdigit(c) || ispunct(c)) // It seems that System Profiler likes only letters and digits...
if (isalpha(c) || isdigit(c) || ispunct(c))
{
// It seems that System Profiler likes only letters and digits...
asciiPartNo[index++] = c;
}
else if (!isascii(c))
{
break;
}
}
return strdup(asciiPartNo);
int mapping []= {0,2,1,3,4,6,5,7,8,10,9,11};
/** Read from smbus the SPD content and interpret it for detecting memory attributes */
/* Read from smbus the SPD content and interpret it for detecting memory attributes */
static void read_smb_intel(pci_dt_t *smbus_dev)
{
int i, speed;
uint8_t spd_size, spd_type;
uint32_t base, mmio, hostc;
// bool dump = false;
RamSlotInfo_t* slot;
uint16_t speed;
uint8_t i, spd_size, spd_type;
uint32_t base, mmio, hostc;
//bool dump = false;
RamSlotInfo_t* slot;
uint16_t cmd = pci_config_read16(smbus_dev->dev.addr, 0x04);
DBG("SMBus CmdReg: 0x%x\n", cmd);
pci_config_write16(smbus_dev->dev.addr, 0x04, cmd | 1);
mmio = pci_config_read32(smbus_dev->dev.addr, 0x10);// & ~0x0f;
base = pci_config_read16(smbus_dev->dev.addr, 0x20) & 0xFFFE;
base = pci_config_read16(smbus_dev->dev.addr, 0x20) & 0xFFFE;
hostc = pci_config_read8(smbus_dev->dev.addr, 0x40);
verbose("Scanning SMBus [%04x:%04x], mmio: 0x%x, ioport: 0x%x, hostc: 0x%x\n",
smbus_dev->vendor_id, smbus_dev->device_id, mmio, base, hostc);
verbose("Scanning SMBus [%04x:%04x], mmio: 0x%x, ioport: 0x%x, hostc: 0x%x\n",
smbus_dev->vendor_id, smbus_dev->device_id, mmio, base, hostc);
//Azi: no use for this!
// getBoolForKey("DumpSPD", &dump, &bootInfo->chameleonConfig);
//Azi: no use for this!
// getBoolForKey("DumpSPD", &dump, &bootInfo->chameleonConfig);
// needed at least for laptops
bool fullBanks = Platform.DMI.MemoryModules == Platform.DMI.CntMemorySlots;
bool fullBanks = Platform.DMI.MemoryModules == Platform.DMI.CntMemorySlots;
char spdbuf[MAX_SPD_SIZE];
// Search MAX_RAM_SLOTS slots
for (i = 0; i < MAX_RAM_SLOTS; i++){
slot = &Platform.RAM.DIMM[i];
spd_size = smb_read_byte_intel(base, 0x50 + i, 0);
DBG("SPD[0] (size): %d @0x%x\n", spd_size, 0x50 + i);
// Check spd is present
if (spd_size && (spd_size != 0xff))
{
// Search MAX_RAM_SLOTS slots
for (i = 0; i < MAX_RAM_SLOTS; i++)
{
// ----
slot = &Platform.RAM.DIMM[i];
spd_size = smb_read_byte_intel(base, 0x50 + i, 0);
DBG("SPD[0] (size): 0x%02x @0x%x\n", spd_size, 0x50 + i);
// Check spd is present
if (spd_size && (spd_size != 0xff))
{
slot->spd = spdbuf;
slot->InUse = true;
// -----
slot->InUse = true;
bzero(slot->spd, spd_size);
// Copy spd data into buffer
bzero(slot->spd, spd_size);
// Copy spd data into buffer
//for (x = 0; x < spd_size; x++) slot->spd[x] = smb_read_byte_intel(base, 0x50 + i, x);
init_spd(slot->spd, base, i);
switch (slot->spd[SPD_MEMORY_TYPE]) {
case SPD_MEMORY_TYPE_SDRAM_DDR2:
slot->ModuleSize = ((1 << ((slot->spd[SPD_NUM_ROWS] & 0x0f) + (slot->spd[SPD_NUM_COLUMNS] & 0x0f) - 17)) *
((slot->spd[SPD_NUM_DIMM_BANKS] & 0x7) + 1) * slot->spd[SPD_NUM_BANKS_PER_SDRAM]);
break;
case SPD_MEMORY_TYPE_SDRAM_DDR3:
slot->ModuleSize = ((slot->spd[4] & 0x0f) + 28 ) + ((slot->spd[8] & 0x7) + 3 );
slot->ModuleSize -= (slot->spd[7] & 0x7) + 25;
slot->ModuleSize = ((1 << slot->ModuleSize) * (((slot->spd[7] >> 3) & 0x1f) + 1));
break;
}
spd_type = (slot->spd[SPD_MEMORY_TYPE] < ((char) 12) ? slot->spd[SPD_MEMORY_TYPE] : 0);
slot->Type = spd_mem_to_smbios[spd_type];
slot->PartNo = getDDRPartNum(slot->spd, base, i);
slot->Vendor = getVendorName(slot, base, i);
slot->SerialNo = getDDRSerial(slot->spd);
init_spd(slot->spd, base, i);
// determine spd speed
speed = getDDRspeedMhz(slot->spd);
if (slot->Frequency<speed) slot->Frequency = speed;
switch (slot->spd[SPD_MEMORY_TYPE])
{
case SPD_MEMORY_TYPE_SDRAM_DDR:
slot->ModuleSize = (((1 << ((slot->spd[SPD_NUM_ROWS] & 0x0f)
+ (slot->spd[SPD_NUM_COLUMNS] & 0x0f) - 17)) *
((slot->spd[SPD_NUM_DIMM_BANKS] & 0x7) + 1) *
slot->spd[SPD_NUM_BANKS_PER_SDRAM])/3)*2;
break;
case SPD_MEMORY_TYPE_SDRAM_DDR2:
slot->ModuleSize = ((1 << ((slot->spd[SPD_NUM_ROWS] & 0x0f) + (slot->spd[SPD_NUM_COLUMNS] & 0x0f) - 17)) *
((slot->spd[SPD_NUM_DIMM_BANKS] & 0x7) + 1) * slot->spd[SPD_NUM_BANKS_PER_SDRAM]);
break;
case SPD_MEMORY_TYPE_SDRAM_DDR3:
slot->ModuleSize = ((slot->spd[4] & 0x0f) + 28 ) + ((slot->spd[8] & 0x7) + 3 );
slot->ModuleSize -= (slot->spd[7] & 0x7) + 25;
slot->ModuleSize = ((1 << slot->ModuleSize) * (((slot->spd[7] >> 3) & 0x1f) + 1));
break;
}
spd_type = (slot->spd[SPD_MEMORY_TYPE] < ((char) 12) ? slot->spd[SPD_MEMORY_TYPE] : 0);
slot->Type = spd_mem_to_smbios[spd_type];
if (slot->Type == UNKNOWN_MEM_TYPE)
{
continue;
}
slot->PartNo = getDDRPartNum(slot->spd, base, i);
slot->Vendor = getVendorName(slot, base, i);
slot->SerialNo = getDDRSerial(slot->spd);
// determine spd speed
speed = getDDRspeedMhz(slot->spd);
if (slot->Frequency<speed)
{
slot->Frequency = speed;
}
// pci memory controller if available, is more reliable
if (Platform.RAM.Frequency > 0) {
if (Platform.RAM.Frequency > 0)
{
uint32_t freq = (uint32_t)Platform.RAM.Frequency / 500000;
// now round off special cases
uint32_t fmod100 = freq %100;
switch(fmod100) {
switch(fmod100)
{
case 1:freq--;break;
case 32:freq++;break;
case 65:freq++; break;
slot->Frequency,
slot->Vendor,
slot->PartNo,
slot->SerialNo);
slot->SerialNo);
slot->InUse = true;
}
}
// laptops sometimes show slot 0 and 2 with slot 1 empty when only 2 slots are presents so:
Platform.DMI.DIMM[i]=
i>0 && Platform.RAM.DIMM[1].InUse==false && fullBanks && Platform.DMI.CntMemorySlots == 2 ?
mapping[i] : i; // for laptops case, mapping setup would need to be more generic than this
// laptops sometimes show slot 0 and 2 with slot 1 empty when only 2 slots are presents so:
Platform.DMI.DIMM[i]=
(uint32_t)((i>0 && Platform.RAM.DIMM[1].InUse==false && !fullBanks && Platform.DMI.CntMemorySlots == 2) ?
mapping[i] : i); // for laptops case, mapping setup would need to be more generic than this
slot->spd = NULL;
} // for
} // for
}
static struct smbus_controllers_t smbus_controllers[] = {
// Info from here: http://cateee.net/lkddb/web-lkddb/I2C_I801.html
{0x8086, 0x269B, "ESB2",read_smb_intel },
{0x8086, 0x25A4, "6300ESB",read_smb_intel },
{0x8086, 0x24C3, "ICH4",read_smb_intel },
{0x8086, 0x24D3, "ICH5",read_smb_intel },
{0x8086, 0x266A, "ICH6",read_smb_intel },
{0x8086, 0x27DA, "ICH7",read_smb_intel },
{0x8086, 0x283E, "ICH8",read_smb_intel },
{0x8086, 0x2930, "ICH9",read_smb_intel },
{0x8086, 0x3A30, "ICH10R",read_smb_intel },
{0x8086, 0x3A60, "ICH10B",read_smb_intel },
{0x8086, 0x3B30, "5 Series",read_smb_intel },
{0x8086, 0x1C22, "6 Series",read_smb_intel },
{0x8086, 0x1D22, "C600/X79 Series",read_smb_intel },
{0x8086, 0x1E22, "7 Series",read_smb_intel },
{0x8086, 0x5032, "EP80579",read_smb_intel },
{0x8086, 0x8C22, "8 Series",read_smb_intel },
{0x8086, 0x9C22, "Lynx Point-LP", read_smb_intel }
{0x8086, 0x1C22, "6 Series", read_smb_intel },
{0x8086, 0x1D22, "C600/X79 Series", read_smb_intel },
{0x8086, 0x1D70, "C600/X79 Series", read_smb_intel },
{0x8086, 0x1D71, "C608/C606/X79 Series", read_smb_intel },
{0x8086, 0x1D72, "C608", read_smb_intel },
{0x8086, 0x1E22, "7 Series/C210 Series", read_smb_intel },
{0x8086, 0x2330, "DH89xxCC", read_smb_intel },
{0x8086, 0x2413, "82801AA", read_smb_intel },
{0x8086, 0x2423, "82801BA/BAM", read_smb_intel },
{0x8086, 0x2443, "82801BA/BAM", read_smb_intel },
{0x8086, 0x2483, "82801CA/CAM", read_smb_intel },
{0x8086, 0x24C3, "82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M)", read_smb_intel },
{0x8086, 0x24D3, "82801EB/ER (ICH5/ICH5R)", read_smb_intel },
{0x8086, 0x25A4, "6300ESB", read_smb_intel },
{0x8086, 0x266A, "82801FB/FBM/FR/FW/FRW (ICH6 Family)", read_smb_intel },
{0x8086, 0x269B, "631xESB/632xESB/3100", read_smb_intel },
{0x8086, 0x27DA, "N10/ICH 7 Family", read_smb_intel },
{0x8086, 0x283E, "82801H (ICH8 Family) ", read_smb_intel },
{0x8086, 0x2930, "82801I (ICH9 Family)", read_smb_intel },
{0x8086, 0x3A30, "82801JI (ICH10 Family)", read_smb_intel },
{0x8086, 0x3A60, "82801JD/DO (ICH10 Family)", read_smb_intel },
{0x8086, 0x3B30, "5 Series/3400 Series", read_smb_intel },
{0x8086, 0x5032, "EP80579", read_smb_intel },
{0x8086, 0x8C22, "8 Series/C220", read_smb_intel },
{0x8086, 0x9C22, "Lynx Point-LP", read_smb_intel }
};
// find_and_read_smbus_controller(root_pci_dev);
bool find_and_read_smbus_controller(pci_dt_t* pci_dt)
{
pci_dt_t*current = pci_dt;
int i;
pci_dt_t*current = pci_dt;
int i;
while (current) {
while (current)
{
#if 0
printf("%02x:%02x.%x [%04x] [%04x:%04x] :: %s\n",
current->dev.bits.bus, current->dev.bits.dev, current->dev.bits.func,
current->class_id, current->vendor_id, current->device_id,
get_pci_dev_path(current));
printf("%02x:%02x.%x [%04x] [%04x:%04x] :: %s\n",
current->dev.bits.bus, current->dev.bits.dev, current->dev.bits.func,
current->class_id, current->vendor_id, current->device_id,
get_pci_dev_path(current));
#endif
for ( i = 0; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ )
{
if (current->vendor_id == smbus_controllers[i].vendor &&
current->device_id == smbus_controllers[i].device)
{
smbus_controllers[i].read_smb(current); // read smb
return true;
}
}
find_and_read_smbus_controller(current->children);
current = current->next;
}
return false; // not found
for ( i = 0; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ )
{
if (current->vendor_id == smbus_controllers[i].vendor && current->device_id == smbus_controllers[i].device)
{
smbus_controllers[i].read_smb(current); // read smb
return true;
}
}
find_and_read_smbus_controller(current->children);
current = current->next;
}
return false; // not found
}
void scan_spd(PlatformInfo_t *p)
{
find_and_read_smbus_controller(root_pci_dev);
find_and_read_smbus_controller(root_pci_dev);
}
trunk/i386/libsaio/spd.h
1616
1717
1818
19
19
2020
2121
2222
......
3838
3939
4040
41
4142
4243
4344
......
130131
131132
132133
134
135
136
133137
134138
135139
......
141145
142146
143147
148
144149
145150
146151
uint32_tvendor;
uint32_tdevice;
char*name;
void (*read_smb)(pci_dt_t *smbus_dev);
void (*read_smb)(pci_dt_t *smbus_dev);
};
/* Byte numbers. */
#define SPD_NUM_MANUFACTURER_BYTES 0 /* Number of bytes used by module manufacturer */
#define SPD_TOTAL_SPD_MEMORY_SIZE 1 /* Total SPD memory size */
// (Essentially) common to DDR & DDR2
#define SPD_MEMORY_TYPE 2 /* (Fundamental) memory type */
#define SPD_NUM_ROWS 3 /* Number of row address bits */
#define SPD_NUM_COLUMNS 4 /* Number of column address bits */
#define ERROR_SCHEME_NONE0
#define ERROR_SCHEME_PARITY1
#define ERROR_SCHEME_ECC2
#define DDR2_DATA_PARITY(1<<0)
#define DDR2_DATA_ECC(1<<1)
#define DDR2_ADDRESS_PARITY(1<<2)
/* SPD_ACCEPTABLE_CAS_LATENCIES values. */
// TODO: Check values.
#define SPD_CAS_LATENCY_3_50x20
#define SPD_CAS_LATENCY_4_00x40
#define SPD_CAS_LATENCY_DDR2_2(1 << 2)
#define SPD_CAS_LATENCY_DDR2_3(1 << 3)
#define SPD_CAS_LATENCY_DDR2_4(1 << 4)
#define SPD_CAS_LATENCY_DDR2_5(1 << 5)
trunk/i386/libsaio/bios.h
3232
3333
3434
35
36
37
38
39
40
35
36
37
38
39
40
4141
4242
4343
44
45
46
47
48
49
50
51
52
53
54
55
56
57
44
45
46
47
48
49
50
51
52
53
54
55
56
57
5858
5959
6060
61
62
63
64
65
66
67
68
69
70
71
72
61
62
63
64
65
66
67
68
69
70
71
72
7373
7474
75
76
77
75
76
77
7878
79
79
8080
8181
8282
8383
8484
8585
86
87
88
89
86
87
88
89
9090
91
91
9292
9393
9494
......
9696
9797
9898
99
100
101
102
99
100
101
102
103103
104104
105105
#include "bootargs.h"
typedef union {
unsigned int rx;
unsigned short rr;
struct {
unsigned char l;
unsigned char h;
} r;
unsigned int rx;
unsigned short rr;
struct {
unsigned char l;
unsigned char h;
} r;
} machineRegister_t;
typedef struct {
unsigned short cf :1;
unsigned short :1;
unsigned short pf :1;
unsigned short :1;
unsigned short af :1;
unsigned short :1;
unsigned short zf :1;
unsigned short sf :1;
unsigned short tf :1;
unsigned short _if :1;
unsigned short df :1;
unsigned short of :1;
unsigned short iopl:2;
unsigned short nt :1;
unsigned short cf :1;
unsigned short :1;
unsigned short pf :1;
unsigned short :1;
unsigned short af :1;
unsigned short :1;
unsigned short zf :1;
unsigned short sf :1;
unsigned short tf :1;
unsigned short _if :1;
unsigned short df :1;
unsigned short of :1;
unsigned short iopl:2;
unsigned short nt :1;
} machineFlags_t;
typedef struct {
unsigned int intno;
machineRegister_t eax;
machineRegister_t ebx;
machineRegister_t ecx;
machineRegister_t edx;
machineRegister_t edi;
machineRegister_t esi;
machineRegister_t ebp;
unsigned short cs;
unsigned short ds;
unsigned short es;
machineFlags_t flags;
unsigned int intno;
machineRegister_t eax;
machineRegister_t ebx;
machineRegister_t ecx;
machineRegister_t edx;
machineRegister_t edi;
machineRegister_t esi;
machineRegister_t ebp;
unsigned short cs;
unsigned short ds;
unsigned short es;
machineFlags_t flags;
} biosBuf_t;
#define EBIOS_FIXED_DISK_ACCESS 0x01
#define EBIOS_LOCKING_ACCESS 0x02
#define EBIOS_ENHANCED_DRIVE_INFO 0x04
#define EBIOS_FIXED_DISK_ACCESS0x01
#define EBIOS_LOCKING_ACCESS0x02
#define EBIOS_ENHANCED_DRIVE_INFO0x04
#define BASE_HD_DRIVE 0x80
#define BASE_HD_DRIVE0x80
#if 0
/*
* ACPI defined memory range types.
*/
enum {
kMemoryRangeUsable = 1, // RAM usable by the OS.
kMemoryRangeReserved = 2, // Reserved. (Do not use)
kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed.
kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use)
kMemoryRangeUsable = 1, // RAM usable by the OS.
kMemoryRangeReserved = 2, // Reserved. (Do not use)
kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed.
kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use)
/* Undefined types should be treated as kMemoryRangeReserved */
/* Undefined types should be treated as kMemoryRangeReserved */
};
#endif
* Memory range descriptor.
*/
typedef struct MemoryRange {
unsigned long long base; // 64-bit base address
unsigned long long length; // 64-bit length in bytes
unsigned long type; // type of memory range
unsigned long reserved;
unsigned long long base; // 64-bit base address
unsigned long long length; // 64-bit length in bytes
unsigned long type; // type of memory range
unsigned long reserved;
} MemoryRange;
#endif /* !__LIBSAIO_BIOS_H */
trunk/i386/libsaio/gma.c
354354
355355
356356
357
357
358358
359359
360360
......
388388
389389
390390
391
392
391
393392
394393
395394
396395
397
398
396
399397
400398
401399
{
if (intel_gfx_chipsets[i].model == ((device_id << 16) | vendor_id))
{
snprintf(desc, sizeof(desc), "%s %s", INTEL_NAME, intel_gfx_chipsets[i].label_info);
snprintf(desc, sizeof(desc), "%s %s", INTEL_NAME, intel_gfx_chipsets[i].label_info);
return desc;
}
}
verbose("Class code: [%04x]\n%s [%04x:%04x] (rev %02x)\nSubsystem: [%04x:%04x] :: %s\n",
gma_dev->class_id, model, gma_dev->vendor_id, gma_dev->device_id, gma_dev->revision_id, gma_dev->subsys_id.subsys.vendor_id, gma_dev->subsys_id.subsys.device_id, devicepath);
if (!string)
{
if (!string) {
string = devprop_create_string();
}
struct DevPropDevice *device = devprop_add_device(string, devicepath);
if (!device)
{
if (!device) {
printf("Failed initializing dev-prop string dev-entry.\n");
pause();
return false;
trunk/i386/libsaio/pci_root.c
7979
8080
8181
82
82
8383
8484
8585
......
105105
106106
107107
108
108
109109
110110
111111
// Try using the file specified with the DSDT option
if (getValueForKey(kDSDT, &dsdt_filename, &len, &bootInfo->chameleonConfig))
{
snprintf(dsdt_dirSpec, sizeof(dsdt_dirSpec), dsdt_filename);
snprintf(dsdt_dirSpec, sizeof(dsdt_dirSpec), dsdt_filename);
}
else
{
}
if (read (fd, new_dsdt, fsize) != fsize) {
verbose("[ERROR] read %s failed\n", dsdt_filename);
free(new_dsdt);
free(new_dsdt);
close (fd);
goto out;
}
trunk/i386/libsaio/aml_generator.c
55
66
77
8
89
910
1011
1112
12
13
1314
1415
1516
......
2425
2526
2627
27
28
28
2929
3030
3131
......
3535
3636
3737
38
38
3939
40
41
40
41
4242
43
43
4444
4545
4646
......
4949
5050
5151
52
52
5353
54
54
5555
5656
5757
5858
5959
6060
61
61
6262
6363
64
64
6565
6666
6767
68
68
6969
70
70
7171
72
72
7373
7474
7575
7676
7777
7878
79
79
8080
81
8182
8283
8384
8485
85
86
8687
87
88
8889
89
90
90
9191
92
92
9393
9494
9595
......
9797
9898
9999
100
100
101101
102
102
103103
104
105
104
106105
107
108106
109107
110108
111109
112
113110
114111
115112
116
113
117114
118
115
119116
120
121
117
122118
123119
124120
125121
126122
127123
128
129124
130125
131126
132
127
133128
134
129
135130
136
137
131
138132
139133
140134
......
143137
144138
145139
146
147140
148141
149142
150
143
151144
152
145
153146
154
155
147
156148
157149
158150
......
165157
166158
167159
168
169160
170161
171162
172
163
173164
174
175
165
176166
177167
178168
179
180169
181170
182171
183172
184
173
185174
186
175
176
177
178
187179
180
188181
189
182
183
184
190185
191
192
186
193187
194188
195189
196
197
198190
199
191
200192
201
202
203
204
205
193
194
195
196
197
206198
207
199
200
208201
209202
210
211
203
212204
213
205
214206
215207
216208
217
209
210
218211
219212
220
221
213
214
222215
223216
224
217
225218
226
227
219
220
228221
229222
230
223
231224
232
225
233226
234
235
227
236228
237229
238230
239231
240
241232
242233
243234
244
235
245236
246
237
247238
248
249
239
250240
251241
252242
253243
244
245
254246
247
248
249
250
251
252
253
254
255
256
257
258
255259
256260
257261
258
262
259263
260
264
261265
262
263
266
264267
265268
266269
267270
268271
269
270272
271273
272274
273
275
274276
275
277
276278
277
278
279
279280
280281
281282
......
287288
288289
289290
290
291
291292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
292417
293418
294
419
295420
296
421
297422
298423
299
424
300425
301426
302
427
303428
304
305
306
307
429
308430
309
310
431
432
311433
312
313
434
435
314436
315437
316
438
317439
318440
319441
320442
321
322
443
323444
445
446
324447
325448
449
450
326451
452
327453
328454
329455
456
457
458
459
460
461
330462
331463
332464
......
334466
335467
336468
337
338
469
339470
340
341
342
471
343472
344473
345
346474
347475
348476
......
350478
351479
352480
481
482
353483
354484
355485
356
357486
358487
359
360488
361489
362490
363
491
364492
365493
366494
367495
368496
369497
370
498
371499
372500
373501
......
375503
376504
377505
378
506
379507
380508
381509
......
385513
386514
387515
388
516
389517
390518
391519
......
399527
400528
401529
402
530
403531
404
405
532
406533
407534
408535
409536
410537
411538
412
539
413540
414
415
416
417
418
419
420
421
422
423
424
425
426
541
542
543
544
545
546
547
548
427549
428
429
430
431
432
550
551
552
433553
434554
435555
......
437557
438558
439559
440
560
441561
442
443
444
562
563
564
445565
446
447
566
448567
449568
450569
451570
571
572
573
574
575
576
577
578
579
580
581
582
452583
584
453585
586
454587
455588
456589
457590
458591
459592
460
461
593
462594
463
464
465
595
466596
467597
468598
......
473603
474604
475605
606
607
476608
477609
478610
......
481613
482614
483615
484
616
617
485618
486
487
488
489
490619
491620
492621
493
494
622
623
624
625
495626
496627
497628
498629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
* Created by Mozodojo on 20/07/10.
* Copyright 2010 mozo. All rights reserved.
*
* additions and corrections by Slice and pcj, 2012.
*/
#include "aml_generator.h"
bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node)
bool aml_add_to_parent(AML_CHUNK* parent, AML_CHUNK* node)
{
if (parent && node)
{
verbose("aml_add_to_parent: Node doesn't support child nodes!\n");
return false;
case AML_CHUNK_NAME:
if (parent->First)
{
if (parent->First) {
verbose("aml_add_to_parent: Name node supports only one child node!\n");
return false;
}
break;
}
if (!parent->First)
if (!parent->First) {
parent->First = node;
if (parent->Last)
}
if (parent->Last) {
parent->Last->Next = node;
}
parent->Last = node;
return true;
return false;
}
struct aml_chunk* aml_create_node(struct aml_chunk* parent)
AML_CHUNK* aml_create_node(AML_CHUNK* parent)
{
struct aml_chunk* node = (struct aml_chunk*)malloc(sizeof(struct aml_chunk));
AML_CHUNK* node = (AML_CHUNK*)malloc(sizeof(AML_CHUNK));
aml_add_to_parent(parent, node);
return node;
}
void aml_destroy_node(struct aml_chunk* node)
void aml_destroy_node(AML_CHUNK* node)
{
// Delete child nodes
struct aml_chunk* child = node->First;
AML_CHUNK* child = node->First;
while (child)
{
struct aml_chunk* next = child->Next;
AML_CHUNK* next = child->Next;
if (child->Buffer)
if (child->Buffer) {
free(child->Buffer);
}
free(child);
child = next;
}
// Free node
if (node->Buffer)
if (node->Buffer) {
free(node->Buffer);
}
free(node);
}
struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size)
AML_CHUNK* aml_add_buffer(AML_CHUNK* parent, char* buffer, uint32_t size)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_NONE;
node->Length = size;
node->Length = (uint16_t)size;
node->Buffer = malloc(node->Length);
memcpy(node->Buffer, buffer, node->Length);
}
return node;
}
struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value)
AML_CHUNK* aml_add_byte(AML_CHUNK* parent, uint8_t value)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_BYTE;
node->Length = 1;
node->Buffer = malloc(node->Length);
node->Buffer[0] = value;
}
return node;
}
struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value)
AML_CHUNK* aml_add_word(AML_CHUNK* parent, uint16_t value)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_WORD;
node->Length = 2;
node->Buffer = malloc(node->Length);
node->Buffer[0] = value & 0xff;
node->Buffer[1] = value >> 8;
}
return node;
}
struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value)
AML_CHUNK* aml_add_dword(AML_CHUNK* parent, uint32_t value)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_DWORD;
node->Length = 4;
node->Buffer = malloc(node->Length);
node->Buffer[2] = (value >> 16) & 0xff;
node->Buffer[3] = (value >> 24) & 0xff;
}
return node;
}
struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value)
AML_CHUNK* aml_add_qword(AML_CHUNK* parent, uint64_t value)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_QWORD;
node->Length = 8;
node->Buffer = malloc(node->Length);
node->Buffer[6] = (value >> 48) & 0xff;
node->Buffer[7] = (value >> 56) & 0xff;
}
return node;
}
unsigned int aml_fill_simple_name(char* buffer, const char* name)
uint32_t aml_fill_simple_name(char* buffer, char* name)
{
if (strlen(name) < 4)
{
if (strlen(name) < 4) {
verbose("aml_fill_simple_name: simple name %s has incorrect lengh! Must be 4.\n", name);
return 0;
}
memcpy(buffer, name, 4);
return 4;
}
unsigned int aml_fill_name(struct aml_chunk* node, const char* name)
uint32_t aml_fill_name(AML_CHUNK* node, char* name)
{
if (!node)
int len, offset, count;
uint32_t root = 0;
if (!node) {
return 0;
}
int len = strlen(name), offset = 0, count = len / 4;
len = strlen(name);
offset = 0;
count = len >> 2;
if ((len % 4) > 1 || count == 0)
{
if ((len % 4) > 1 || count == 0) {
verbose("aml_fill_name: pathname %s has incorrect length! Must be 4, 8, 12, 16, etc...\n", name);
return 0;
}
unsigned int root = 0;
if ((len % 4) == 1 && name[0] == '\\')
if (((len % 4) == 1) && (name[0] == '\\')) {
root++;
if (count == 1)
{
node->Length = 4 + root;
node->Buffer = malloc(node->Length);
}
if (count == 1) {
node->Length = (uint16_t)(4 + root);
node->Buffer = malloc(node->Length+4);
memcpy(node->Buffer, name, 4 + root);
return node->Length;
offset += 4 + root;
return (uint32_t)offset;
}
if (count == 2)
{
if (count == 2) {
node->Length = 2 + 8;
node->Buffer = malloc(node->Length);
node->Buffer = malloc(node->Length+4);
node->Buffer[offset++] = 0x5c; // Root Char
node->Buffer[offset++] = 0x2e; // Double name
memcpy(node->Buffer+offset, name + root, 8);
return node->Length;
offset += 8;
return (uint32_t)offset;
}
node->Length = 3 + count*4;
node->Buffer = malloc(node->Length);
node->Length = (uint16_t)(3 + (count << 2));
node->Buffer = malloc(node->Length+4);
node->Buffer[offset++] = 0x5c; // Root Char
node->Buffer[offset++] = 0x2f; // Multi name
node->Buffer[offset++] = count; // Names count
node->Buffer[offset++] = (char)count; // Names count
memcpy(node->Buffer+offset, name + root, count*4);
return node->Length;
offset += count*4;
return (uint32_t)offset;
}
struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name)
AML_CHUNK* aml_add_scope(AML_CHUNK* parent, char* name)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_SCOPE;
aml_fill_name(node, name);
}
return node;
}
struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name)
AML_CHUNK* aml_add_name(AML_CHUNK* parent, char* name)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_NAME;
aml_fill_name(node, name);
}
return node;
}
AML_CHUNK* aml_add_method(AML_CHUNK* parent, char* name, uint8_t args)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
unsigned int offset = aml_fill_name(node, name);
node->Type = AML_CHUNK_METHOD;
node->Length++;
node->Buffer[offset] = args;
}
return node;
}
struct aml_chunk* aml_add_package(struct aml_chunk* parent)
AML_CHUNK* aml_add_package(AML_CHUNK* parent)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_PACKAGE;
node->Length = 1;
node->Buffer = malloc(node->Length);
}
return node;
}
struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2)
AML_CHUNK* aml_add_alias(AML_CHUNK* parent, char* name1, char* name2)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_ALIAS;
node->Length = 8;
return node;
}
unsigned char aml_get_size_length(unsigned int size)
AML_CHUNK* aml_add_return_name(AML_CHUNK* parent, char* name)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_RETURN;
aml_fill_name(node, name);
}
return node;
}
AML_CHUNK* aml_add_return_byte(AML_CHUNK* parent, uint8_t value)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_RETURN;
aml_add_byte(node, value);
}
return node;
}
AML_CHUNK* aml_add_device(AML_CHUNK* parent, char* name)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_DEVICE;
aml_fill_name(node, name);
}
return node;
}
AML_CHUNK* aml_add_local0(AML_CHUNK* parent)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_LOCAL0;
node->Length = 1;
}
return node;
}
AML_CHUNK* aml_add_store(AML_CHUNK* parent)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_STORE_OP;
node->Length = 1;
}
return node;
}
AML_CHUNK* aml_add_byte_buffer(AML_CHUNK* parent, char* data, uint32_t size)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
int offset = 0;
node->Type = AML_CHUNK_BUFFER;
node->Length = (uint8_t)(size + 2);
node->Buffer = malloc (node->Length);
node->Buffer[offset++] = AML_CHUNK_BYTE; //0x0A
node->Buffer[offset++] = (char)size;
memcpy(node->Buffer+offset,data, node->Length);
}
return node;
}
AML_CHUNK* aml_add_string_buffer(AML_CHUNK* parent, char* StringBuf)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
unsigned int offset = 0;
unsigned int len = strlen(StringBuf)+1;
node->Type = AML_CHUNK_BUFFER;
node->Length = (uint8_t)(len + 3);
node->Buffer = malloc (node->Length);
node->Buffer[offset++] = AML_CHUNK_BYTE;
node->Buffer[offset++] = (char)len;
memcpy(node->Buffer+offset, StringBuf, len);
node->Buffer[offset+len] = '\0';
}
return node;
}
AML_CHUNK* aml_add_string(AML_CHUNK* parent, char* StringBuf)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
int len = strlen(StringBuf);
node->Type = AML_CHUNK_STRING;
node->Length = (uint8_t)(len + 1);
node->Buffer = malloc (len);
memcpy(node->Buffer, StringBuf, len);
node->Buffer[len] = '\0';
}
return node;
}
AML_CHUNK* aml_add_return(AML_CHUNK* parent)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_RETURN;
//aml_add_byte(node, value);
}
return node;
}
uint8_t aml_get_size_length(uint32_t size)
{
if (size + 1 <= 0x3f)
return 1;
else if (size + 2 <= 0x3fff)
else if (size + 2 <= 0xfff) /* Encode in 4 bits and 1 byte */
return 2;
else if (size + 3 <= 0x3fffff)
else if (size + 3 <= 0xfffff) /* Encode in 4 bits and 2 bytes */
return 3;
return 4;
return 4; /* Encode 0xfffffff in 4 bits and 2 bytes */
}
unsigned int aml_calculate_size(struct aml_chunk* node)
uint32_t aml_calculate_size(AML_CHUNK* node)
{
if (node)
{
node->Size = 0;
if (node) {
// Calculate child nodes size
struct aml_chunk* child = node->First;
unsigned char child_count = 0;
AML_CHUNK* child = node->First;
uint8_t child_count = 0;
while (child)
{
node->Size = 0;
while (child) {
child_count++;
node->Size += aml_calculate_size(child);
node->Size += (uint16_t)aml_calculate_size(child);
child = child->Next;
}
switch (node->Type)
{
switch (node->Type) {
case AML_CHUNK_NONE:
case AML_STORE_OP:
case AML_CHUNK_LOCAL0:
node->Size += node->Length;
break;
case AML_CHUNK_METHOD:
case AML_CHUNK_SCOPE:
case AML_CHUNK_BUFFER:
node->Size += 1 + node->Length;
node->Size += aml_get_size_length(node->Size);
break;
case AML_CHUNK_DEVICE:
node->Size += 2 + node->Length;
node->Size += aml_get_size_length(node->Size);
break;
case AML_CHUNK_PACKAGE:
node->Buffer[0] = child_count;
node->Size += 1 + node->Length;
break;
case AML_CHUNK_BYTE:
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
{
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) {
node->Size += node->Length;
}
else
{
} else {
node->Size += 1 + node->Length;
}
break;
case AML_CHUNK_WORD:
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
case AML_CHUNK_NAME:
case AML_CHUNK_RETURN:
case AML_CHUNK_STRING:
node->Size += 1 + node->Length;
break;
}
return node->Size;
}
return 0;
}
unsigned int aml_write_byte(unsigned char value, char* buffer, unsigned int offset)
uint32_t aml_write_byte(uint8_t value, char* buffer, uint32_t offset)
{
buffer[offset++] = value;
return offset;
}
unsigned int aml_write_word(unsigned int value, char* buffer, unsigned int offset)
uint32_t aml_write_word(uint16_t value, char* buffer, uint32_t offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = value >> 8;
return offset;
}
unsigned int aml_write_dword(unsigned long value, char* buffer, unsigned int offset)
uint32_t aml_write_dword(uint32_t value, char* buffer, uint32_t offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = (value >> 8) & 0xff;
return offset;
}
unsigned int aml_write_qword(unsigned long long value, char* buffer, unsigned int offset)
uint32_t aml_write_qword(uint64_t value, char* buffer, uint32_t offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = (value >> 8) & 0xff;
return offset;
}
unsigned int aml_write_buffer(const char* value, unsigned int size, char* buffer, unsigned int offset)
uint32_t aml_write_buffer(const char* value, uint32_t size, char* buffer, uint32_t offset)
{
if (size > 0)
{
if (size > 0) {
memcpy(buffer + offset, value, size);
}
return offset + size;
}
unsigned int aml_write_size(unsigned int size, char* buffer, unsigned int offset)
uint32_t aml_write_size(uint32_t size, char* buffer, uint32_t offset)
{
if (size <= 0x3f)
{
buffer[offset++] = size;
}
else if (size <= 0x3fff)
{
buffer[offset++] = 0x40 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
}
else if (size <= 0x3fffff)
{
buffer[offset++] = 0x80 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
if (size <= 0x3f) { /* simple 1 byte length in 6 bits */
buffer[offset++] = (char)size;
} else if (size <= 0xfff) {
buffer[offset++] = 0x40 | (size & 0xf); /* 0x40 is type, 0x0X is first nibble of length */
buffer[offset++] = (size >> 4) & 0xff; /* +1 bytes for rest length */
} else if (size <= 0xfffff) {
buffer[offset++] = 0x80 | (size & 0xf); /* 0x80 is type, 0x0X is first nibble of length */
buffer[offset++] = (size >> 4) & 0xff; /* +2 bytes for rest length */
buffer[offset++] = (size >> 12) & 0xff;
}
else
{
buffer[offset++] = 0xc0 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
} else {
buffer[offset++] = 0xc0 | (size & 0xf); /* 0xC0 is type, 0x0X is first nibble of length */
buffer[offset++] = (size >> 4) & 0xff; /* +3 bytes for rest length */
buffer[offset++] = (size >> 12) & 0xff;
buffer[offset++] = (size >> 20) & 0xff;
}
return offset;
}
unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset)
uint32_t aml_write_node(AML_CHUNK* node, char* buffer, uint32_t offset)
{
if (node && buffer)
{
unsigned int old = offset;
if (node && buffer) {
uint32_t old = offset;
AML_CHUNK* child = node->First;
switch (node->Type)
{
switch (node->Type) {
case AML_CHUNK_NONE:
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
case AML_CHUNK_LOCAL0:
case AML_STORE_OP:
offset = aml_write_byte(node->Type, buffer, offset);
break;
case AML_CHUNK_DEVICE:
offset = aml_write_byte(AML_CHUNK_OP, buffer, offset);
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_size(node->Size-3, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
case AML_CHUNK_SCOPE:
case AML_CHUNK_METHOD:
case AML_CHUNK_PACKAGE:
case AML_CHUNK_BUFFER:
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_size(node->Size-1, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
case AML_CHUNK_BYTE:
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
{
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) {
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
}
else
{
} else {
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
}
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
case AML_CHUNK_NAME:
case AML_CHUNK_RETURN:
case AML_CHUNK_STRING:
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
break;
}
struct aml_chunk* child = node->First;
while (child) {
offset = aml_write_node(child, buffer, offset);
while (child)
{
offset = aml_write_node(child, buffer, offset);
child = child->Next;
}
if (offset - old != node->Size)
verbose("Node size incorrect: 0x%x\n", node->Type);
if (offset - old != node->Size) {
verbose("Node size incorrect: type=0x%x size=%x offset=%x\n",
node->Type, node->Size, (offset - old));
}
}
return offset;
}
//the procedure can find array char sizeof N inside part of large array "dsdt" size of len
int32_t FindBin (uint8_t *dsdt, uint32_t len, uint8_t *bin, unsigned int N)
{
uint32_t i, j;
bool eq;
for (i=0; i<len-N; i++) {
eq = true;
for (j=0; j<N; j++) {
if (dsdt[i+j] != bin[j]) {
eq = false;
break;
}
}
if (eq) {
return i;
}
}
return 0;
}
uint32_t get_size(uint8_t* Buffer, uint32_t adr)
{
uint32_t temp;
temp = Buffer[adr] & 0xF0; //keep bits 0x30 to check if this is valid size field
if(temp <= 0x30) { // 0
temp = Buffer[adr];
} else if(temp == 0x40){// 4
temp = (Buffer[adr] - 0x40) << 0|
Buffer[adr+1] << 4;
} else if(temp == 0x80){// 8
temp = (Buffer[adr] - 0x80) << 0|
Buffer[adr+1] << 4|
Buffer[adr+2] << 12;
} else if(temp == 0xC0){// C
temp = (Buffer[adr] - 0xC0) << 0|
Buffer[adr+1] << 4|
Buffer[adr+2] << 12|
Buffer[adr+3] << 20;
} else {
verbose("wrong pointer to size field at %x\n", adr);
return 0; //this means wrong pointer to size field
}
return temp;
}
trunk/i386/libsaio/befs.c
2020
2121
2222
23
23
2424
2525
2626
......
2828
2929
3030
31
31
3232
33
3334
3435
3536
/* Find BeFS signature */
bool BeFSProbe (const void *buf)
{
return (OSReadLittleInt32(buf+0x220,0)==SUPER_BLOCK_MAGIC1);
return (OSReadLittleInt32(buf+0x220,0) == SUPER_BLOCK_MAGIC1);
}
/* Find BeFS volume label */
{
char * buf=malloc (BeFSProbeSize);
str[0]=0;
if (!buf)
if (!buf) {
return;
}
Seek(ih, 0);
Read(ih, (long)buf, BeFSProbeSize);
if (!BeFSProbe (buf))
trunk/i386/libsaio/aml_generator.h
1212
1313
1414
15
16
17
18
19
20
21
22
23
24
25
26
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
2759
28
29
30
31
60
61
62
3263
33
34
35
64
3665
3766
3867
3968
4069
70
71
4172
4273
4374
4475
4576
46
47
48
49
50
51
52
53
54
55
56
57
58
59
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
6095
96
97
98
99
100
101
102
103
104
105
106
61107
#include "libsaio.h"
#defineAML_CHUNK_NONE0xff
#defineAML_CHUNK_ZERO0x00
#defineAML_CHUNK_ONE0x01
#defineAML_CHUNK_ALIAS0x06
#defineAML_CHUNK_NAME0x08
#defineAML_CHUNK_BYTE0x0A
#defineAML_CHUNK_WORD0x0B
#defineAML_CHUNK_DWORD0x0C
#defineAML_CHUNK_STRING0x0D
#defineAML_CHUNK_QWORD0x0E
#defineAML_CHUNK_SCOPE0x10
#defineAML_CHUNK_PACKAGE0x12
//
// Primary OpCode
//
#defineAML_CHUNK_ZERO 0x00 // AML_ZERO_OP
#defineAML_CHUNK_ONE 0x01 // AML_ONE_OP
#defineAML_CHUNK_ALIAS 0x06 // AML_ALIAS_OP
#defineAML_CHUNK_NAME 0x08 // AML_NAME_OP
#defineAML_CHUNK_BYTE 0x0A // AML_BYTE_PREFIX
#defineAML_CHUNK_WORD 0x0B // AML_WORD_PREFIX
#defineAML_CHUNK_DWORD 0x0C // AML_DWORD_PREFIX
#defineAML_CHUNK_STRING 0x0D // AML_STRING_PREFIX
#defineAML_CHUNK_QWORD 0x0E // AML_QWORD_PREFIX
#defineAML_CHUNK_SCOPE 0x10 // AML_SCOPE_OP
#define AML_CHUNK_BUFFER 0x11 // AML_BUFFER_OP
#defineAML_CHUNK_PACKAGE 0x12 // AML_PACKAGE_OP
#define AML_CHUNK_VAR_PACKAGE 0x13 // AML_VAR_PACKAGE_OP
#defineAML_CHUNK_METHOD 0x14 // AML_METHOD_OP
#define AML_CHUNK_STRING_BUFFER0x15 //
#define AML_CHUNK_LOCAL0 0x60 // AML_LOCAL0
#define AML_CHUNK_LOCAL1 0x61 // AML_LOCAL1
#define AML_CHUNK_LOCAL2 0x62 // AML_LOCAL2
#define AML_CHUNK_LOCAL3 0x63 // AML_LOCAL3
#define AML_CHUNK_LOCAL4 0x64 // AML_LOCAL4
#define AML_CHUNK_LOCAL5 0x65 // AML_LOCAL5
#define AML_CHUNK_LOCAL6 0x66 // AML_LOCAL6
#define AML_CHUNK_LOCAL7 0x67 // AML_LOCAL7
#define AML_CHUNK_ARG0 0x68 // AML_ARG0
#define AML_CHUNK_ARG1 0x69 // AML_ARG1
#define AML_CHUNK_ARG2 0x6A // AML_ARG2
#define AML_CHUNK_ARG3 0x6B // AML_ARG3
#define AML_CHUNK_ARG4 0x6C // AML_ARG4
#define AML_CHUNK_ARG5 0x6D // AML_ARG5
#define AML_CHUNK_ARG6 0x6E // AML_ARG6
#define AML_STORE_OP 0x70 // AML_STORE_OP
#define AML_CHUNK_REFOF 0x71 // AML_REF_OF_OP
#define AML_CHUNK_RETURN 0xA4 // AML_RETURN_OP
#define AML_CHUNK_BRECK 0xA5 // AML_BREAK_OP
#defineAML_CHUNK_NONE 0xff // AML_ONES_OP
//
// Extended OpCode
//
#define AML_CHUNK_OP 0x5B // AML_EXT_OP
#define AML_CHUNK_DEVICE 0x82 // AML_EXT_DEVICE_OP
#define AML_CHUNK_PROCESSOR 0x83 // AML_EXT_PROCESSOR_OP
struct aml_chunk
{
unsigned charType;
unsigned intLength;
struct aml_chunk {
uint8_tType;
uint16_tLength;
char*Buffer;
unsigned intSize;
uint16_tSize;
struct aml_chunk*Next;
struct aml_chunk*First;
struct aml_chunk*Last;
};
typedef struct aml_chunk AML_CHUNK;
static inline bool aml_isvalidchar(char c)
{
return isupper(c) || isdigit(c) || c == '_';
};
bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node);
struct aml_chunk* aml_create_node(struct aml_chunk* parent);
void aml_destroy_node(struct aml_chunk* node);
struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size);
struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value);
struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value);
struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value);
struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value);
struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name);
struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name);
struct aml_chunk* aml_add_package(struct aml_chunk* parent);
struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2);
unsigned int aml_calculate_size(struct aml_chunk* node);
unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset);
bool aml_add_to_parent(AML_CHUNK* parent, AML_CHUNK* node);
AML_CHUNK* aml_create_node(AML_CHUNK* parent);
void aml_destroy_node(AML_CHUNK* node);
AML_CHUNK* aml_add_buffer(AML_CHUNK* parent, char* buffer, uint32_t size);
AML_CHUNK* aml_add_byte(AML_CHUNK* parent, uint8_t value);
AML_CHUNK* aml_add_word(AML_CHUNK* parent, uint16_t value);
AML_CHUNK* aml_add_dword(AML_CHUNK* parent, uint32_t value);
AML_CHUNK* aml_add_qword(AML_CHUNK* parent, uint64_t value);
AML_CHUNK* aml_add_scope(AML_CHUNK* parent, char* name);
AML_CHUNK* aml_add_name(AML_CHUNK* parent, char* name);
AML_CHUNK* aml_add_method(AML_CHUNK* parent, char* name, uint8_t args);
AML_CHUNK* aml_add_return_name(AML_CHUNK* parent, char* name);
AML_CHUNK* aml_add_return_byte(AML_CHUNK* parent, uint8_t value);
AML_CHUNK* aml_add_package(AML_CHUNK* parent);
AML_CHUNK* aml_add_alias(AML_CHUNK* parent, char* name1, char* name2);
uint32_t aml_calculate_size(AML_CHUNK* node);
uint32_t aml_write_node(AML_CHUNK* node, char* buffer, uint32_t offset);
uint32_t aml_write_size(uint32_t size, char* buffer, uint32_t offset);
AML_CHUNK* aml_add_string(AML_CHUNK* parent, char* string);
AML_CHUNK* aml_add_byte_buffer(AML_CHUNK* parent, char* data, uint32_t size);
AML_CHUNK* aml_add_string_buffer(AML_CHUNK* parent, char* string);
AML_CHUNK* aml_add_device(AML_CHUNK* parent, char* name);
AML_CHUNK* aml_add_local0(AML_CHUNK* parent);
AML_CHUNK* aml_add_store(AML_CHUNK* parent);
AML_CHUNK* aml_add_return(AML_CHUNK* parent);
int32_t FindBin (uint8_t *dsdt, uint32_t len, uint8_t *bin, unsigned int N);
uint32_t get_size(uint8_t* Buffer, uint32_t adr);
#endif /* !__LIBSAIO_AML_GENERATOR_H */
trunk/i386/libsaio/memvendors.h
646646
647647
648648
649
649
650650
651651
652652
{ 4, 0xfd, "Focus Enhancements"},
{ 4, 0xfe, "Xyratex"},
{ 5, 0x01, "Specular Networks"},
{ 5, 0x02, "PDP Systems"},
{ 5, 0x02, "Patriot Memory (PDP Systems)"},
{ 5, 0x83, "U-Chip Technology Corp."},
{ 5, 0x04, "Silicon Optix"},
{ 5, 0x85, "Greenfield Networks"},
trunk/i386/libsaio/device_inject.c
3131
3232
3333
34
35
34
3635
3736
3837
......
5655
5756
5857
59
60
58
6159
6260
6361
6462
65
66
63
6764
68
69
65
7066
7167
7268
......
7571
7672
7773
78
79
74
75
76
77
8078
8179
8280
8381
8482
8583
86
84
8785
8886
8987
......
10199
102100
103101
104
105
106
102
103
104
107105
108106
109107
......
117115
118116
119117
120
118
121119
122
120
123121
124
125
122
126123
127124
128125
......
132129
133130
134131
135
132
136133
137
134
138135
139
140
136
141137
142138
143139
......
148144
149145
150146
151
152
153
154
147
148
149
150
155151
156152
157153
......
163159
164160
165161
166
162
167163
168164
169165
......
178174
179175
180176
181
182
183
184
185
186
187
188
177
178
179
180
181
182
183
184
185
189186
190187
191188
192
189
193190
194191
195192
196193
197194
198
199
195
196
200197
201
198
202199
203200
204201
......
222219
223220
224221
225
222
226223
227224
228225
229226
230227
231
228
232229
233230
234231
......
294291
295292
296293
297
294
298295
299296
300297
......
310307
311308
312309
313
310
314311
315312
316313
......
410407
411408
412409
413
414
410
411
412
415413
416
414
417415
418
419
420
421
422
423
424
416
417
418
419
420
421
422
425423
426424
char *efi_inject_get_devprop_string(uint32_t *len)
{
if(string)
{
if(string) {
*len = string->length;
return devprop_generate_string(string);
}
/* Use the static "device-properties" boot config key contents if available,
* otheriwse use the generated one.
*/
if (!getValueForKey(kDeviceProperties, &val, &cnt, &bootInfo->chameleonConfig) && string)
{
if (!getValueForKey(kDeviceProperties, &val, &cnt, &bootInfo->chameleonConfig) && string) {
val = (const char*)string;
cnt = strlength * 2;
}
if (cnt > 1)
{
if (cnt > 1) {
binStr = convertHexStr2Binary(val, &cnt2);
if (cnt2 > 0)
{
if (cnt2 > 0) {
DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, binStr);
}
}
struct DevPropString *devprop_create_string(void)
{
string = (struct DevPropString*)malloc(sizeof(struct DevPropString));
if (string == NULL)
return NULL;
if(string == NULL) {
return NULL;
}
memset(string, 0, sizeof(struct DevPropString));
string->length = 12;
string->WHAT2 = 0x01000000;
return string;
}
struct DevPropDevice *devprop_add_device(struct DevPropString *string, char *path)
{
struct DevPropDevice*device = NULL;
}
if (!(device = malloc(sizeof(struct DevPropDevice)))) {
printf("ERROR malloc failed\n");
return NULL;
}
printf("ERROR malloc failed\n");
return NULL;
}
memset(device, 0, sizeof(struct DevPropDevice));
device->acpi_dev_path._UID = getPciRootUID();
x+=strlen(pci_device_string);
curr=x;
while(path[++x] != ',');
if(x-curr == 2)
if(x-curr == 2) {
sprintf(buff, "%c%c", path[curr], path[curr+1]);
else if(x-curr == 1)
} else if(x-curr == 1) {
sprintf(buff, "%c", path[curr]);
else
{
} else {
printf("ERROR parsing device path\n");
numpaths = 0;
break;
x += 3; // 0x
curr = x;
while(path[++x] != ')');
if(x-curr == 2)
if(x-curr == 2) {
sprintf(buff, "%c%c", path[curr], path[curr+1]);
else if(x-curr == 1)
} else if(x-curr == 1) {
sprintf(buff, "%c", path[curr]);
else
{
} else {
printf("ERROR parsing device path\n");
numpaths = 0;
break;
}
}
if (!numpaths) {
free(device);
return NULL;
}
if(!numpaths) {
free(device);
return NULL;
}
device->numentries = 0x00;
device->num_pci_devpaths = numpaths;
device->length = 24 + (6*numpaths);
inti;
inti;
for(i = 0; i < numpaths; i++)
{
device->string = string;
device->data = NULL;
if (!string->entries)
if (!(string->entries = (struct DevPropDevice**) malloc(sizeof(device) * DEV_PROP_DEVICE_MAX_ENTRIES))) {
free(device);
return NULL;
}
/* FIXME: probably needs bounds checking, as well as error handling in event of malloc failure */
if(!string->entries) {
if (!(string->entries = (struct DevPropDevice**) malloc(sizeof(device) * DEV_PROP_DEVICE_MAX_ENTRIES))) {
free(device);
return NULL;
}
}
/* FIXME: probably needs bounds checking, as well as error handling in event of malloc failure */
string->length += device->length;
string->entries[string->numentries++] = (struct DevPropDevice*)malloc(sizeof(device));
string->entries[string->numentries-1] = device;
return device;
}
int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
{
if(!nm || !vl || !len)
if(!nm || !vl || !len) {
return 0;
}
uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
uint8_t *data = (uint8_t*)malloc(length);
{
off += 2;
l = len;
uint32_t *datalength = (uint32_t*)&data[off];
*datalength = l + 4;
*datalength = (uint32_t)(l + 4);
off += 4;
for(i = 0 ; i < l ; i++, off++)
{
data[off] = *vl++;
}
}
}
uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
dp_swap32(string->entries[i]->acpi_dev_path._UID));
buffer += 24;
for(x=0;x < string->entries[i]->num_pci_devpaths; x++)
for(x = 0;x < string->entries[i]->num_pci_devpaths; x++)
{
sprintf(buffer, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type,
string->entries[i]->pci_dev_path[x].subtype,
buffer += 8;
uint8_t *dataptr = string->entries[i]->data;
for(x = 0; x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
for(x = 0; (uint32_t)x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
{
sprintf(buffer, "%02x", *dataptr++);
buffer += 2;
verbose("LAN Controller [%04x:%04x] :: %s\n", eth_dev->vendor_id, eth_dev->device_id, devicepath);
if(!string)
string = devprop_create_string();
if(!string) {
string = devprop_create_string();
}
device = devprop_add_device(string, devicepath);
device = devprop_add_device(string, devicepath);
if(device) {
verbose("Setting up lan keys\n");
devprop_add_network_template(device, eth_dev->vendor_id);
stringdata = (uint8_t*)malloc(sizeof(uint8_t) * string->length);
if(stringdata) {
memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
stringlength = string->length;
}
verbose("Setting up lan keys\n");
devprop_add_network_template(device, eth_dev->vendor_id);
stringdata = (uint8_t*)malloc(sizeof(uint8_t) * string->length);
if(stringdata) {
memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
stringlength = string->length;
}
}
}
trunk/i386/libsaio/hda.c
478478
479479
480480
481
482481
483482
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
510517
511518
512519
513
514
520
521
522
523
524
515525
516526
517527
/* get HDA device name */
static char *get_hda_controller_name(uint16_t controller_device_id, uint16_t controller_vendor_id)
{
int i;
static char desc[128];
for (i = 0; i < HDAC_DEVICES_LEN; i++)
{
if (know_hda_controller[i].model == ((controller_device_id << 16) | controller_vendor_id))
{
if(controller_vendor_id == INTEL_VENDORID){
sprintf(desc, "Intel %s Hight Definition Audio Controller", know_hda_controller[i].desc);
desc[sizeof(desc) - 1] = '\0';
} else if (controller_vendor_id == NVIDIA_VENDORID) {
sprintf(desc, "nVidia %s HDA Controller (HDMi)", know_hda_controller[i].desc);
desc[sizeof(desc) - 1] = '\0';
} else if (controller_vendor_id == ATI_VENDORID) {
sprintf(desc, "ATI %s HDA Controller (HDMi)", know_hda_controller[i].desc);
desc[sizeof(desc) - 1] = '\0';
} else if (controller_vendor_id == RDC_VENDORID) {
sprintf(desc, "RDC %s Hight Definition Audio Controller", know_hda_controller[i].desc);
desc[sizeof(desc) - 1] = '\0';
} else if (controller_vendor_id == VIA_VENDORID) {
sprintf(desc, "VIA %s HDA Controller", know_hda_controller[i].desc);
desc[sizeof(desc) - 1] = '\0';
} else if (controller_vendor_id == SIS_VENDORID) {
sprintf(desc, "SiS %s HDA Controller", know_hda_controller[i].desc);
desc[sizeof(desc) - 1] = '\0';
} else if (controller_vendor_id == ULI_VENDORID) {
sprintf(desc, "ULI %s HDA Controller", know_hda_controller[i].desc);
desc[sizeof(desc) - 1] = '\0';
}
const char* name_format = "Unknown HD Audio device %s";
uint32_t controller_model = ((controller_device_id << 16) | controller_vendor_id);
int i;
/* Get format for vendor ID */
switch (controller_vendor_id) {
case ATI_VENDORID:
name_format = "ATI %s HDA Controller (HDMi)"; break;
case INTEL_VENDORID:
name_format = "Intel %s High Definition Audio Controller"; break;
case NVIDIA_VENDORID:
name_format = "nVidia %s HDA Controller (HDMi)"; break;
case RDC_VENDORID:
name_format = "RDC %s High Definition Audio Controller"; break;
case SIS_VENDORID:
name_format = "SiS %s HDA Controller"; break;
case ULI_VENDORID:
name_format = "ULI %s HDA Controller"; break;
case VIA_VENDORID:
name_format = "VIA %s HDA Controller"; break;
default:
break;
}
for (i = 0; i < HDAC_DEVICES_LEN; i++) {
if (know_hda_controller[i].model == controller_model) {
snprintf(desc, sizeof(desc), name_format, know_hda_controller[i].desc);
return desc;
}
}
sprintf(desc, "Unknown HD Audio device");
desc[sizeof(desc) - 1] = '\0';
/* Not in table */
snprintf(desc, sizeof(desc),
"Unknown HD Audio device, vendor %04x, model %04x",
controller_vendor_id, controller_device_id);
return desc;
}
trunk/i386/libsaio/device_inject.h
4343
4444
4545
46
46
4747
4848
4949
uint16_t numentries;
uint16_t WHAT2;// 0x0000 ?
struct ACPIDevPath acpi_dev_path;// = 0x02010c00 0xd041030a
struct PCIDevPath pci_dev_path[MAX_PCI_DEV_PATHS]; // = 0x01010600 func dev
struct PCIDevPath pci_dev_path[MAX_PCI_DEV_PATHS];// = 0x01010600 func dev
struct DevicePathEnd path_end;// = 0x7fff0400
uint8_t *data;
trunk/i386/libsaio/base64-decode.c
3636
3737
3838
39
40
39
4140
4241
4342
......
6867
6968
7069
71
70
{
/* Wrong base64 string length */
return NULL;
}
}
result = dest = malloc(in_len / 4 * 3 + 1);
if (result == NULL)
return NULL; /* out of memory */
}
/* end of base64.c */
/* end of base64.c */
trunk/i386/libsaio/fdisk.h
3535
3636
3737
38
39
40
38
39
40
4141
42
42
4343
4444
45
45
4646
47
47
4848
49
50
51
52
53
49
50
51
52
53
5454
5555
5656
57
58
57
58
5959
6060
6161
6262
6363
6464
65
66
67
68
69
70
71
72
73
74
65
66
67
68
69
70
71
72
73
74
7575
7676
7777
7878
7979
8080
81
82
83
81
82
83
8484
8585
8686
87
88
89
87
88
89
9090
9191
9292
#ifndef __LIBSAIO_FDISK_H
#define __LIBSAIO_FDISK_H
#define DISK_BLK00/* blkno of boot block */
#define DISK_BLK0SZ512/* size of boot block */
#define DISK_BOOTSZ446/* size of boot code in boot block */
#define DISK_BLK00 /* blkno of boot block */
#define DISK_BLK0SZ512 /* size of boot block */
#define DISK_BOOTSZ446 /* size of boot code in boot block */
#define DISK_SIGNATURE0xAA55/* signature of the boot record */
#define FDISK_NPART4/* number of entries in fdisk table */
#define FDISK_NPART4 /* number of entries in fdisk table */
#define FDISK_ACTIVE0x80/* indicator of active partition */
#define FDISK_NEXTNAME0xA7/* indicator of NeXT partition */
#define FDISK_DOS120x01/* 12-bit fat < 10MB dos partition */
#define FDISK_DOS120x01/* 12-bit fat < 10MB dos partition */
#define FDISK_DOS16S0x04/* 16-bit fat < 32MB dos partition */
#define FDISK_DOSEXT0x05/* extended dos partition */
#define FDISK_DOSEXT0x05/* extended DOS partition */
#define FDISK_DOS16B0x06/* 16-bit fat >= 32MB dos partition */
#define FDISK_NTFS0x07/* NTFS partition */
#define FDISK_SMALLFAT320x0b /* FAT32 partition */
#define FDISK_FAT320x0c/* FAT32 partition */
#define FDISK_DOS16SLBA 0x0e
#define FDISK_LINUX0x83
#define FDISK_NTFS0x07/* NTFS partition */
#define FDISK_SMALLFAT320x0b/* FAT32 partition */
#define FDISK_FAT320x0c/* FAT32 partition */
#define FDISK_DOS16SLBA0x0e /* 16-bit FAT, LBA-mapped */
#define FDISK_LINUX0x83 /* Linux native */
#define FDISK_OPENBSD0xa6 /* OpenBSD FFS partition */
#define FDISK_FREEBSD0xa5 /* FreeBSD UFS2 partition */
#define FDISK_BEFS0xeb /* Haiku BeFS partition */
#define FDISK_UFS0xa8/* Apple UFS partition */
#define FDISK_HFS0xaf/* Apple HFS partition */
#define FDISK_UFS0xa8/* Apple UFS partition */
#define FDISK_HFS0xaf/* Apple HFS partition */
#define FDISK_BOOTER0xab/* Apple booter partition */
/*
* Format of fdisk partion entry (if present).
*/
struct fdisk_part {
unsigned char bootid; /* bootable or not */
unsigned char beghead; /* begining head, sector, cylinder */
unsigned char begsect; /* begcyl is a 10-bit number */
unsigned char begcyl; /* High 2 bits are in begsect */
unsigned char systid; /* OS type */
unsigned char endhead; /* ending head, sector, cylinder */
unsigned char endsect; /* endcyl is a 10-bit number */
unsigned char endcyl; /* High 2 bits are in endsect */
unsigned long relsect; /* partion physical offset on disk */
unsigned long numsect; /* number of sectors in partition */
unsigned char bootid; /* bootable or not */
unsigned char beghead; /* begining head, sector, cylinder */
unsigned char begsect; /* begcyl is a 10-bit number */
unsigned char begcyl; /* High 2 bits are in begsect */
unsigned char systid; /* OS type */
unsigned char endhead; /* ending head, sector, cylinder */
unsigned char endsect; /* endcyl is a 10-bit number */
unsigned char endcyl; /* High 2 bits are in endsect */
unsigned long relsect; /* partion physical offset on disk */
unsigned long numsect; /* number of sectors in partition */
} __attribute__((packed));
/*
* Format of boot block.
*/
struct disk_blk0 {
unsigned char bootcode[DISK_BOOTSZ];
unsigned char parts[FDISK_NPART][sizeof (struct fdisk_part)];
unsigned short signature;
unsigned char bootcode[DISK_BOOTSZ];
unsigned char parts[FDISK_NPART][sizeof (struct fdisk_part)];
unsigned short signature;
};
struct REAL_disk_blk0 {
unsigned char bootcode[DISK_BOOTSZ];
struct fdisk_part parts[FDISK_NPART];
unsigned short signature;
unsigned char bootcode[DISK_BOOTSZ];
struct fdisk_part parts[FDISK_NPART];
unsigned short signature;
} __attribute__((packed));
#endif /* !__LIBSAIO_FDISK_H */
trunk/i386/libsaio/dram_controllers.c
3737
3838
3939
40
40
4141
4242
4343
......
6363
6464
6565
66
66
6767
6868
6969
......
8282
8383
8484
85
85
8686
8787
8888
8989
9090
91
91
9292
93
93
9494
9595
9696
9797
98
98
9999
100
100
101101
102
102
103103
104
104
105105
106
106
107107
108108
109109
......
114114
115115
116116
117
117
118118
119119
120120
......
127127
128128
129129
130
130
131131
132132
133133
......
138138
139139
140140
141
141
142142
143143
144144
......
148148
149149
150150
151
151
152152
153153
154154
......
159159
160160
161161
162
162
163163
164164
165165
166166
167
167
168168
169169
170170
......
175175
176176
177177
178
178
179179
180180
181181
182182
183183
184
184
185185
186
186
187187
188188
189189
190190
191191
192
193
192
193
194194
195
195
196196
197197
198198
......
203203
204204
205205
206
206
207207
208208
209209
......
214214
215215
216216
217
217
218218
219219
220220
......
232232
233233
234234
235
235
236236
237
237
238238
239239
240240
......
244244
245245
246246
247
247
248248
249249
250250
251
251
252252
253253
254254
......
259259
260260
261261
262
262
263263
264264
265265
266266
267267
268
268
269269
270270
271271
272
272
273273
274274
275
275
276276
277277
278
278
279279
280280
281
281
282282
283283
284
284
285285
286286
287
287
288288
289289
290
290
291291
292292
293
293
294294
295295
296
296
297297
298298
299
299
300300
301301
302
302
303303
304304
305
305
306306
307307
308
308
309309
310310
311
312
311
312
313313
314
314
315315
316
316317
317318
318319
......
321322
322323
323324
324
325
325326
326327
327328
328
329
329330
330331
331
332
332333
333334
334
335
335336
336337
337
338
338339
339340
340
341
341342
342343
343
344
344345
345346
346
347
347348
348349
349
350
350351
351352
352
353
353354
354355
355
356
356357
357358
358
359
359
360
360361
361
362
362363
364
363365
364366
365367
366368
367
369
368370
369371
370372
371373
372
374
373375
374376
375
377
376378
377379
378380
379
381
380382
381
382
383
384
383385
384386
385
387
386388
387389
388
390
389391
390392
391
392
393
394
393395
394
396
395397
396398
397
399
398400
399401
400
402
401403
402404
403
405
404406
405
406
407
408
407409
408410
409411
410
412
411413
412414
413415
414416
415417
416
418
417419
418
420
419421
420
422
421423
422
424
423425
426
424427
425428
426
429
427430
428
431
429432
433
430434
431435
432436
433
437
434438
435439
436
440
437441
438442
439
443
440444
441
445
442446
443
447
444448
449
445450
446451
447452
......
449454
450455
451456
452
457
453458
454459
455460
456
461
457462
458463
459
464
460465
461
466
462467
463
468
464469
465
470
466471
472
467473
468474
469475
470476
471
477
472478
473479
474
480
475481
476482
477
483
478484
479485
480
486
481487
482488
483
489
484490
485
491
486492
487
493
488494
489
495
490496
497
491498
492499
493500
......
496503
497504
498505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
499527
500528
501
529
502530
503
504
531
532
505533
506534
507535
508536
509537
510538
511
512
513
514
539
540
541
542
543
544
515545
516546
517547
518
548
549
550
519551
520552
521553
522
523
524
525
526
527
528
529
554
555
556
557
558
559
560
561
530562
531563
532564
533565
534566
535
567
536568
537569
538570
539571
540572
541
542
573
574
543575
544576
545
546
547
548
549
577
578
579
580
581
550582
583
551584
552
585
553586
587
554588
555
589
556590
591
557592
558593
559
560
561
562
563
564
565
594
595
596
597
598
599
566600
601
567602
static void setup_p35(pci_dt_t *dram_dev)
{
uint32_t dev0;
// Activate MMR I/O
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
if (!(dev0 & 0x1))
did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), PCI_DEVICE_ID);
vid &= 0xFFFF;
did &= 0xFF00;
if(vid == 0x8086 && did >= 0x2C00)
{
nhm_bus = possible_nhm_bus[i];
uint32_t dev0, mch_ratio, mch_cfg, mch_fsb;
long *ptr;
// Find Ratio
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0xC00);
mch_cfg = *ptr & 0xFFFF;
mch_ratio = 100000;
switch (mch_cfg & 7)
{
case 0: mch_fsb = 1066; break;
case 1: mch_fsb = 533; break;
default:
default:
case 2: mch_fsb = 800; break;
case 3: mch_fsb = 667; break;
case 3: mch_fsb = 667; break;
case 4: mch_fsb = 1333; break;
case 6: mch_fsb = 1600; break;
case 6: mch_fsb = 1600; break;
}
DBG("mch_fsb %d\n", mch_fsb);
switch (mch_fsb)
{
case 533:
case 3:mch_ratio = 300000; break;
}
break;
default:
case 800:
switch ((mch_cfg >> 4) & 7)
case 5:mch_ratio = 333333; break; // 3.333333333
}
break;
case 1066:
switch ((mch_cfg >> 4) & 7)
{
case 5:mch_ratio = 250000; break;
}
break;
case 1333:
switch ((mch_cfg >> 4) & 7)
{
case 5:mch_ratio = 200000; break;
}
break;
case 1600:
switch ((mch_cfg >> 4) & 7)
{
}
break;
}
DBG("mch_ratio %d\n", mch_ratio);
// Compute RAM Frequency
Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000;
DBG("ram_fsb %d\n", Platform.RAM.Frequency);
}
uint32_t dev0, mch_ratio, mch_cfg, mch_fsb;
long *ptr;
// Find Ratio
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0xC00);
mch_cfg = *ptr & 0xFFFF;
mch_ratio = 100000;
switch (mch_cfg & 7)
{
case 1: mch_fsb = 533; break;
default:
case 2:mch_fsb = 800; break;
case 3:mch_fsb = 667; break;
case 6:mch_fsb = 1066; break;
case 3:mch_fsb = 667; break;
case 6:mch_fsb = 1066; break;
}
switch (mch_fsb)
{
case 533:
case 3:mch_ratio = 200000; break;
}
break;
case 667:
switch ((mch_cfg >> 4)& 7)
{
case 5:mch_ratio = 240000; break;
}
break;
default:
case 800:
switch ((mch_cfg >> 4) & 7)
case 5:mch_ratio = 150000; break;
case 6:mch_ratio = 200000; break;
}
}
// Compute RAM Frequency
Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000;
}
static void get_fsb_nhm(pci_dt_t *dram_dev)
{
uint32_t mch_ratio, mc_dimm_clk_ratio;
// Get the clock ratio
mc_dimm_clk_ratio = pci_config_read16(PCIADDR(nhm_bus, 3, 4), 0x54 );
mch_ratio = (mc_dimm_clk_ratio & 0x1F);
// Compute RAM Frequency
Platform.RAM.Frequency = Platform.CPU.FSBFrequency * mch_ratio / 2;
}
// Get i965 Memory Timings
static void get_timings_i965(pci_dt_t *dram_dev)
{
{
// Thanks for CDH optis
uint32_t dev0, c0ckectrl, c1ckectrl, offset;
uint32_t ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register;
long *ptr;
// Read MMR Base Address
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0x260);
c0ckectrl = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + 0x660);
c1ckectrl = *ptr & 0xFFFFFFFF;
// If DIMM 0 not populated, check DIMM 1
((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x400);
ptr = (long*)(dev0 + offset + 0x29C);
ODT_Control_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x250);
Precharge_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x252);
ACT_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x258);
Read_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x244);
Misc_Register = *ptr & 0xFFFFFFFF;
// 965 Series only support DDR2
Platform.RAM.Type = SMB_MEM_TYPE_DDR2;
// CAS Latency (tCAS)
Platform.RAM.CAS = ((ODT_Control_Register >> 17) & 7) + 3;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = (Read_Register >> 16) & 0xF;
// RAS Precharge (tRP)
Platform.RAM.TRP = (ACT_Register >> 13) & 0xF;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = (Precharge_Register >> 11) & 0x1F;
if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF))
if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) {
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
else
} else {
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
}
}
// Get im965 Memory Timings
// Thanks for CDH optis
uint32_t dev0, c0ckectrl, c1ckectrl, offset, ODT_Control_Register, Precharge_Register;
long *ptr;
// Read MMR Base Address
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0x1200);
c0ckectrl = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + 0x1300);
c1ckectrl = *ptr & 0xFFFFFFFF;
// If DIMM 0 not populated, check DIMM 1
((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x100);
ptr = (long*)(dev0 + offset + 0x121C);
ODT_Control_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x1214);
Precharge_Register = *ptr & 0xFFFFFFFF;
// Series only support DDR2
Platform.RAM.Type = SMB_MEM_TYPE_DDR2;
// CAS Latency (tCAS)
Platform.RAM.CAS = ((ODT_Control_Register >> 23) & 7) + 3;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = ((Precharge_Register >> 5) & 7) + 2;
// RAS Precharge (tRP)
Platform.RAM.TRP= (Precharge_Register & 7) + 2;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = (Precharge_Register >> 21) & 0x1F;
if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF))
if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) {
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
else
} else {
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
}
}
// Get P35 Memory Timings
static void get_timings_p35(pci_dt_t *dram_dev)
{
{
// Thanks for CDH optis
unsigned long dev0, Memory_Check, c0ckectrl, c1ckectrl, offset;
unsigned long ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register;
long *ptr;
//Device_ID = pci_config_read16(dram_dev->dev.addr, 0x02);
//Device_ID &= 0xFFFF;
// Now, read MMR Base Address
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0x260);
c0ckectrl = *ptr & 0xFFFFFFFF;
c0ckectrl = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + 0x660);
c1ckectrl = *ptr & 0xFFFFFFFF;
// If DIMM 0 not populated, check DIMM 1
((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x400);
ptr = (long*)(dev0 + offset + 0x265);
ODT_Control_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x25D);
ptr = (long*)(dev0 + offset + 0x25D);
Precharge_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x252);
ACT_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x258);
Read_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x244);
Misc_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x1E8);
Memory_Check = *ptr & 0xFFFFFFFF;
Memory_Check = *ptr & 0xFFFFFFFF;
// On P45, check 1A8
if(dram_dev->device_id > 0x2E00) {
ptr = (long*)(dev0 + offset + 0x1A8);
Memory_Check = *ptr & 0xFFFFFFFF;
Memory_Check = *ptr & 0xFFFFFFFF;
Memory_Check >>= 2;
Memory_Check &= 1;
Memory_Check = !Memory_Check;
} else {
ptr = (long*)(dev0 + offset + 0x1E8);
Memory_Check = *ptr & 0xFFFFFFFF;
Memory_Check = *ptr & 0xFFFFFFFF;
}
// Determine DDR-II or DDR-III
if (Memory_Check & 1)
if (Memory_Check & 1) {
Platform.RAM.Type = SMB_MEM_TYPE_DDR2;
else
} else {
Platform.RAM.Type = SMB_MEM_TYPE_DDR3;
}
// CAS Latency (tCAS)
if(dram_dev->device_id > 0x2E00)
if(dram_dev->device_id > 0x2E00) {
Platform.RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 6;
else
} else {
Platform.RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 9;
}
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = (Read_Register >> 17) & 0xF;
// RAS Precharge (tRP)
Platform.RAM.TRP = (ACT_Register >> 13) & 0xF;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = Precharge_Register & 0x3F;
// Channel configuration
if (((c0ckectrl >> 20) & 0xF) && ((c1ckectrl >> 20) & 0xF))
if (((c0ckectrl >> 20) & 0xF) && ((c1ckectrl >> 20) & 0xF)) {
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
else
} else {
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
}
}
// Get Nehalem Memory Timings
{
unsigned long mc_channel_bank_timing, mc_control, mc_channel_mrs_value;
int fvc_bn = 4;
// Find which channels are populated
mc_control = pci_config_read16(PCIADDR(nhm_bus, 3, 0), 0x48);
mc_control = (mc_control >> 8) & 0x7;
// DDR-III
Platform.RAM.Type = SMB_MEM_TYPE_DDR3;
// Get the first valid channel
if(mc_control & 1)
if(mc_control & 1) {
fvc_bn = 4;
else if(mc_control & 2)
} else if(mc_control & 2) {
fvc_bn = 5;
else if(mc_control & 7)
} else if(mc_control & 7) {
fvc_bn = 6;
}
// Now, detect timings
mc_channel_bank_timing = pci_config_read32(PCIADDR(nhm_bus, fvc_bn, 0), 0x88);
mc_channel_mrs_value = pci_config_read32(PCIADDR(nhm_bus, fvc_bn, 0), 0x70);
// CAS Latency (tCAS)
Platform.RAM.CAS = ((mc_channel_mrs_value >> 4) & 0xF ) + 4;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = (mc_channel_bank_timing >> 9) & 0xF;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = (mc_channel_bank_timing >> 4) & 0x1F;
// RAS Precharge (tRP)
Platform.RAM.TRP = mc_channel_bank_timing & 0xF;
// Single , Dual or Triple Channels
if (mc_control == 1 || mc_control == 2 || mc_control == 4 )
if (mc_control == 1 || mc_control == 2 || mc_control == 4 ) {
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
else if (mc_control == 7)
} else if (mc_control == 7) {
Platform.RAM.Channels = SMB_MEM_CHANNEL_TRIPLE;
else
} else {
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
}
}
static struct mem_controller_t dram_controllers[] = {
{ 0, 0, "",NULL, NULL, NULL },
// Intel
//{ 0x8086, 0x0100, "2rd Gen Core processor",NULL, NULL, NULL },
//{ 0x8086, 0x0104, "2rd Gen Core processor",NULL, NULL, NULL },
//{ 0x8086, 0x010C, "Xeon E3-1200/2rd Gen Core processor",NULL, NULL, NULL },
//{ 0x8086, 0x0150, "Xeon E3-1200 v2/3rd Gen Core processor",NULL, NULL, NULL },
//{ 0x8086, 0x0154, "3rd Gen Core processor",NULL, NULL, NULL },
//{ 0x8086, 0x0158, "Xeon E3-1200 v2/Ivy Bridge",NULL, NULL, NULL },
//{ 0x8086, 0x015C, "Xeon E3-1200 v2/3rd Gen Core processor",NULL, NULL, NULL },
//{ 0x8086, 0x0BF0, "Atom Processor D2xxx/N2xxx",NULL, NULL, NULL },
//{ 0x8086, 0x0BF1, "Atom Processor D2xxx/N2xxx",NULL, NULL, NULL },
//{ 0x8086, 0x0BF2, "Atom Processor D2xxx/N2xxx",NULL, NULL, NULL },
//{ 0x8086, 0x0BF3, "Atom Processor D2xxx/N2xxx",NULL, NULL, NULL },
//{ 0x8086, 0x0BF4, "Atom Processor D2xxx/N2xxx",NULL, NULL, NULL },
//{ 0x8086, 0x0BF5, "Atom Processor D2xxx/N2xxx",NULL, NULL, NULL },
//{ 0x8086, 0x0BF6, "Atom Processor D2xxx/N2xxx",NULL, NULL, NULL },
//{ 0x8086, 0x0BF7, "Atom Processor D2xxx/N2xxx",NULL, NULL, NULL },
//{ 0x8086, 0x0C00, "Haswell",NULL, NULL, NULL },
//{ 0x8086, 0x0C04, "Haswell",NULL, NULL, NULL },
//{ 0x8086, 0x0C08, "Haswell",NULL, NULL, NULL },
{ 0x8086, 0x7190, "VMWare",NULL, NULL, NULL },
{ 0x8086, 0x1A30, "i845",NULL, NULL, NULL },
{ 0x8086, 0x1A30, "82845 845 [Brookdale]",NULL, NULL, NULL },
{ 0x8086, 0x2970, "i946PL/GZ",setup_p35, get_fsb_i965,get_timings_i965},
{ 0x8086, 0x2990, "Q963/Q965",setup_p35, get_fsb_i965,get_timings_i965},
{ 0x8086, 0x2970, "82946GZ/PL/GL",setup_p35, get_fsb_i965,get_timings_i965},
{ 0x8086, 0x2990, "82Q963/Q965",setup_p35, get_fsb_i965,get_timings_i965},
{ 0x8086, 0x29A0, "P965/G965",setup_p35, get_fsb_i965,get_timings_i965},
{ 0x8086, 0x2A00, "GM965/GL960",setup_p35, get_fsb_im965,get_timings_im965},
{ 0x8086, 0x2A10, "GME965/GLE960",setup_p35, get_fsb_im965,get_timings_im965},
{ 0x8086, 0x2A40, "PM/GM45/47",setup_p35, get_fsb_im965,get_timings_im965},
{ 0x8086, 0x29B0, "Q35",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x29C0, "P35/G33",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x29D0, "Q33",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x29E0, "X38/X48",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x29B0, "82Q35 Express",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x29C0, "82G33/G31/P35/P31",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x29D0, "82Q33 Express",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x29E0, "82X38/X48 Express",setup_p35, get_fsb_i965,get_timings_p35},
//{ 0x8086, 0x29F0, "3200/3210 Chipset",NULL, NULL, NULL },
{ 0x8086, 0x2E00, "Eaglelake",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x2E10, "Q45/Q43",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x2E20, "P45/G45",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x2E30, "G41",setup_p35, get_fsb_i965,get_timings_p35},
{ 0x8086, 0x2E30, "G41",setup_p35, get_fsb_i965,get_timings_p35},
//{ 0x8086, 0x2E40, "4 Series Chipset",NULL, NULL, NULL },
//{ 0x8086, 0x2E90, "4 Series Chipset",NULL, NULL, NULL },
{ 0x8086, 0xD131, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0xD132, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3400, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3401, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3402, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3403, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3404, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3405, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3406, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3407, "NHM IMC",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3400, "5520/5500/X58",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3401, "5520/5500/X58",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3402, "5520/5500/X58",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3403, "5500",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3404, "5520/5500/X58",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3405, "5520/5500/X58",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3406, "5520",setup_nhm, get_fsb_nhm,get_timings_nhm},
{ 0x8086, 0x3407, "5520/5500/X58",setup_nhm, get_fsb_nhm,get_timings_nhm},
};
static const char *memory_channel_types[] =
{
"Unknown", "Single", "Dual", "Triple"
};
};
void scan_dram_controller(pci_dt_t *dram_dev)
{
int i;
for(i = 1; i < sizeof(dram_controllers) / sizeof(dram_controllers[0]); i++)
if ((dram_controllers[i].vendor == dram_dev->vendor_id)
&& (dram_controllers[i].device == dram_dev->device_id))
{
if ((dram_controllers[i].vendor == dram_dev->vendor_id) && (dram_controllers[i].device == dram_dev->device_id))
{
verbose("%s%s DRAM Controller [%4x:%4x] at %02x:%02x.%x\n",
(dram_dev->vendor_id == 0x8086) ? "Intel " : "" ,
dram_controllers[i].name, dram_dev->vendor_id, dram_dev->device_id,
dram_dev->dev.bits.bus, dram_dev->dev.bits.dev, dram_dev->dev.bits.func);
if (dram_controllers[i].initialise != NULL)
(dram_dev->vendor_id == 0x8086) ? "Intel Corporation " : "" ,
dram_controllers[i].name, dram_dev->vendor_id, dram_dev->device_id,
dram_dev->dev.bits.bus, dram_dev->dev.bits.dev, dram_dev->dev.bits.func);
if (dram_controllers[i].initialise != NULL) {
dram_controllers[i].initialise(dram_dev);
}
if (dram_controllers[i].poll_timings != NULL)
if (dram_controllers[i].poll_timings != NULL) {
dram_controllers[i].poll_timings(dram_dev);
}
if (dram_controllers[i].poll_speed != NULL)
if (dram_controllers[i].poll_speed != NULL) {
dram_controllers[i].poll_speed(dram_dev);
}
verbose("Frequency detected: %d MHz (%d) %s Channel \n\tCAS:%d tRC:%d tRP:%d RAS:%d (%d-%d-%d-%d)\n",
(uint32_t)Platform.RAM.Frequency / 1000000,
(uint32_t)Platform.RAM.Frequency / 500000,
memory_channel_types[Platform.RAM.Channels]
,Platform.RAM.CAS, Platform.RAM.TRC, Platform.RAM.TRP, Platform.RAM.RAS
,Platform.RAM.CAS, Platform.RAM.TRC, Platform.RAM.TRP, Platform.RAM.RAS
);
//getchar();
(uint32_t)Platform.RAM.Frequency / 1000000,
(uint32_t)Platform.RAM.Frequency / 500000,
memory_channel_types[Platform.RAM.Channels]
,Platform.RAM.CAS, Platform.RAM.TRC, Platform.RAM.TRP, Platform.RAM.RAS
,Platform.RAM.CAS, Platform.RAM.TRC, Platform.RAM.TRP, Platform.RAM.RAS);
//getchar();
}
}
}
trunk/i386/libsaio/ntfs.c
270270
271271
272272
273
274
275
273
274
276275
277276
278277
......
310309
311310
312311
313
312
314313
314
315315
316316
317317
......
339339
340340
341341
342
342
343343
344344
345345
346346
347347
348348
349
349
350350
351351
352352
353
353
354354
355355
356356
357
357
358358
359359
//verbose("NTFS: lseek to $Volume failed: %s\n", strerror(errno));
goto error;
}
if (read(fd, buf, mftRecordSize) != mftRecordSize)
{
//verbose("NTFS: error reading MFT $Volume record: %s\n", strerror(errno));
if (read(fd, buf, mftRecordSize) != mftRecordSize) {
//verbose("NTFS: error reading MFT $Volume record: %s\n", strerror(errno));
goto error;
}
#endif
struct bootfile *boot;
void *buf = malloc(MAX_BLOCK_SIZE);
if ( !buf )
if ( !buf ) {
return -1;
}
/*
* Read the boot sector, check signatures, and do some minimal
(unsigned short)boot->bf_volsn & 0xFFFF);
return 0;
}
}
bool NTFSProbe(const void * buffer)
{
bool result = false;
const struct bootfile* part_bootfile = buffer;// NTFS boot sector structure
// Looking for NTFS signature.
if (strncmp((const char *)part_bootfile->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) == 0)
result = true;
// If not NTFS, maybe it is EXFAT
if (!result)
result = EXFATProbe(buffer);
return result;
}
trunk/i386/libsaio/platform.c
3737
3838
3939
40
41
42
40
41
42
43
44
45
4346
4447
45
48
4649
47
50
4851
52
4953
50
54
5155
52
56
5357
5458
5559
56
57
58
60
61
62
5963
6064
61
62
63
65
66
67
6468
6569
6670
}
/** scan mem for memory autodection purpose */
void scan_mem() {
static bool done = false;
if (done) return;
void scan_mem()
{
static bool done = false;
if (done) {
return;
}
/* our code only works on Intel chipsets so make sure here */
if (pci_config_read16(PCIADDR(0, 0x00, 0), 0x00) != 0x8086)
if (pci_config_read16(PCIADDR(0, 0x00, 0), 0x00) != 0x8086) {
bootInfo->memDetect = false;
else
} else {
bootInfo->memDetect = true;
}
/* manually */
getBoolForKey(kUseMemDetect, &bootInfo->memDetect, &bootInfo->chameleonConfig);
getBoolForKey(kUseMemDetect, &bootInfo->memDetect, &bootInfo->chameleonConfig);
if (bootInfo->memDetect) {
if (bootInfo->memDetect) {
if (dram_controller_dev != NULL) {
scan_dram_controller(dram_controller_dev); // Rek: pci dev ram controller direct and fully informative scan ...
}
scan_spd(&Platform);
}
done = true;
scan_spd(&Platform);
}
done = true;
}
/**
Scan platform hardware information, called by the main entry point (common_boot() )
_before_ bootConfig xml parsing settings are loaded
/*
* Scan platform hardware information, called by the main entry point (common_boot() )
* _before_ bootConfig xml parsing settings are loaded
*/
void scan_platform(void)
{
trunk/i386/libsaio/cpu.c
310310
311311
312312
313
313314
314315
315316
......
421422
422423
423424
424
425
425
426426
427
428
427
429428
430429
431430
......
529528
530529
531530
532
533
534
531
535532
536533
537534
......
576573
577574
578575
579
580
576
581577
582578
583
584
585
586
587
579
580
588581
589582
590583
......
622615
623616
624617
625
626
627
628
629
630
618
619
620
631621
632622
633623
634
635
624
636625
637
638
639
626
640627
641628
642629
643
644
645
646
647
630
631
648632
649
650
651
633
652634
653635
654636
655637
656
657
658
659
660
638
639
661640
662641
663
664
665
642
666643
667644
668645
......
689666
690667
691668
692
693
694
695
696
697
698
699
700
669
670
671
672
673
674
675
676
677
701678
702679
703680
p->CPU.Stepping= bitfield(p->CPU.CPUID[CPUID_1][0], 3, 0);
p->CPU.Model= bitfield(p->CPU.CPUID[CPUID_1][0], 7, 4);
p->CPU.Family= bitfield(p->CPU.CPUID[CPUID_1][0], 11, 8);
p->CPU.Type = bitfield(p->CPU.CPUID[CPUID_1][0], 13, 12);
p->CPU.ExtModel= bitfield(p->CPU.CPUID[CPUID_1][0], 19, 16);
p->CPU.ExtFamily= bitfield(p->CPU.CPUID[CPUID_1][0], 27, 20);
fsbFrequency = 0;
cpuFrequency = 0;
if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f)))
{
if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) {
int intelCPU = p->CPU.Model;
if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03))
{
if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)){
/* Nehalem CPU model */
if (p->CPU.Family == 0x06 && (p->CPU.Model == CPU_MODEL_NEHALEM||
p->CPU.Model == CPU_MODEL_FIELDS||
myfsb = fsbFrequency / 1000000;
verbose("Sticking with [BCLK: %dMhz, Bus-Ratio: %d]\n", myfsb, max_ratio/10);
currcoef = bus_ratio_max;
}
else
{
} else {
msr = rdmsr64(MSR_IA32_PERF_STATUS);
DBG("msr(%d): ia32_perf_stat 0x%08x\n", __LINE__, bitfield(msr, 31, 0));
currcoef = bitfield(msr, 12, 8);
}
}
/* Mobile CPU */
if (rdmsr64(MSR_IA32_PLATFORM_ID) & (1<<28))
{
if (rdmsr64(MSR_IA32_PLATFORM_ID) & (1<<28)) {
p->CPU.Features |= CPU_FEATURE_MOBILE;
}
}
else if ((p->CPU.Vendor == CPUID_VENDOR_AMD) && (p->CPU.Family == 0x0f))
{
switch(p->CPU.ExtFamily)
{
} else if ((p->CPU.Vendor == CPUID_VENDOR_AMD) && (p->CPU.Family == 0x0f)) {
switch(p->CPU.ExtFamily) {
case 0x00: /* K8 */
msr = rdmsr64(K8_FIDVID_STATUS);
maxcoef = bitfield(msr, 21, 16) / 2 + 4;
break;
}
if (maxcoef)
{
if (currdiv)
{
if (!currcoef)
{
if (maxcoef) {
if (currdiv) {
if (!currcoef) {
currcoef = maxcoef;
}
if (!cpuFrequency)
{
if (!cpuFrequency) {
fsbFrequency = ((tscFrequency * currdiv) / currcoef);
}
else
{
} else {
fsbFrequency = ((cpuFrequency * currdiv) / currcoef);
}
DBG("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
}
else
{
if (!cpuFrequency)
{
} else {
if (!cpuFrequency) {
fsbFrequency = (tscFrequency / maxcoef);
}
else
{
} else {
fsbFrequency = (cpuFrequency / maxcoef);
}
DBG("%d\n", currcoef);
}
}
else if (currcoef)
{
if (currdiv)
{
} else if (currcoef) {
if (currdiv) {
fsbFrequency = ((tscFrequency * currdiv) / currcoef);
DBG("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
}
else
{
} else {
fsbFrequency = (tscFrequency / currcoef);
DBG("%d\n", currcoef);
}
// keep formatted with spaces instead of tabs
DBG("CPU: Brand String: %s\n", p->CPU.BrandString);
DBG("CPU: Vendor/Family/ExtFamily: 0x%x/0x%x/0x%x\n", p->CPU.Vendor, p->CPU.Family, p->CPU.ExtFamily);
DBG("CPU: Model/ExtModel/Stepping: 0x%x/0x%x/0x%x\n", p->CPU.Model, p->CPU.ExtModel, p->CPU.Stepping);
DBG("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n", p->CPU.MaxCoef, p->CPU.CurrCoef);
DBG("CPU: MaxDiv/CurrDiv: 0x%x/0x%x\n", p->CPU.MaxDiv, p->CPU.CurrDiv);
DBG("CPU: TSCFreq: %dMHz\n", p->CPU.TSCFrequency / 1000000);
DBG("CPU: FSBFreq: %dMHz\n", p->CPU.FSBFrequency / 1000000);
DBG("CPU: CPUFreq: %dMHz\n", p->CPU.CPUFrequency / 1000000);
DBG("CPU: NoCores/NoThreads: %d/%d\n", p->CPU.NoCores, p->CPU.NoThreads);
DBG("CPU: Features: 0x%08x\n", p->CPU.Features);
DBG("CPU: Vendor/Family/ExtFamily: 0x%x/0x%x/0x%x\n", p->CPU.Vendor, p->CPU.Family, p->CPU.ExtFamily);
DBG("CPU: Model/ExtModel/Stepping: 0x%x/0x%x/0x%x\n", p->CPU.Model, p->CPU.ExtModel, p->CPU.Stepping);
DBG("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n", p->CPU.MaxCoef, p->CPU.CurrCoef);
DBG("CPU: MaxDiv/CurrDiv: 0x%x/0x%x\n", p->CPU.MaxDiv, p->CPU.CurrDiv);
DBG("CPU: TSCFreq: %dMHz\n", p->CPU.TSCFrequency / 1000000);
DBG("CPU: FSBFreq: %dMHz\n", p->CPU.FSBFrequency / 1000000);
DBG("CPU: CPUFreq: %dMHz\n", p->CPU.CPUFrequency / 1000000);
DBG("CPU: NoCores/NoThreads: %d/%d\n", p->CPU.NoCores, p->CPU.NoThreads);
DBG("CPU: Features: 0x%08x\n", p->CPU.Features);
#if DEBUG_CPU
pause();
#endif
trunk/i386/libsaio/platform.h
129129
130130
131131
132
133
132134
133135
134136
135137
136
138
137139
140
138141
139142
140143
......
168171
169172
170173
171
172
173
174
174
175
176
177
175178
176179
177180
uint8_tBankConnCnt;
} RamSlotInfo_t;
//==============================================================================
typedef struct _PlatformInfo_t {
struct CPU {
uint32_tFeatures;// CPU Features like MMX, SSE2, VT, MobileCPU
uint32_tVendor;// Vendor
uint32_tSignature;// Signature
uint32_tSignature;// Processor Signature
uint32_tStepping;// Stepping
uint32_tType;// Type
uint32_tModel;// Model
uint32_tExtModel;// Extended Model
uint32_tFamily;// Family
} RAM;
struct DMI {
intMaxMemorySlots;// number of memory slots populated by SMBIOS
intCntMemorySlots;// number of memory slots counted
intMemoryModules;// number of memory modules installed
intDIMM[MAX_RAM_SLOTS];// Information and SPD mapping for each slot
intMaxMemorySlots;// number of memory slots populated by SMBIOS
intCntMemorySlots;// number of memory slots counted
intMemoryModules;// number of memory modules installed
intDIMM[MAX_RAM_SLOTS];// Information and SPD mapping for each slot
} DMI;
uint8_tType; // System Type: 1=Desktop, 2=Portable... according ACPI2.0 (FACP: PM_Profile)
trunk/i386/libsaio/disk.c
139139
140140
141141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
142
143
162144
163
164
165
166
167
168
169
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
170167
171
172168
173
169
170
171
174172
175
173
174
175
176
177
178
179
180
181
182
183
176184
177185
178186
179187
180188
181189
182
183
190
191
184192
185193
194
195
186196
187197
188198
189
199
190200
191
192
193
201
202
203
204
205
206
207
194208
195
209
196210
197211
198212
199213
200
201
202
203
204
205
206
207
214
215
216
217
218
219
220
221
222
208223
209224
210225
211226
212
213
227
228
214229
215
216
230
217231
218
219
232
233
234
235
236
237
238
220239
221240
222241
......
231250
232251
233252
234
235
236
253
254
255
237256
238
239
240
241
257
258
259
260
242261
243
244
245
246
247
248
249
250
251
252
253
254
255
262
263
264
265
256266
257
267
268
269
270
271
272
273
258274
259
260
275
276
277
278
279
261280
262
263
264
265
266
267
268
269
270
271
272
281
273282
274
275
276
283
277284
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
285
286
297287
298
299
300
301
302
303
304
305
306
307
308
288
289
290
291
292
293
294
309295
310
311
296
297
298
312299
313
314
315
316
317
300
301
302
303
304
305
306
318307
319
320
321
322
323
324
325
326
327
328
329
330
331
332
308
309
310
311
312
333313
334
314
315
316
317
318
319
320
335321
336
337
338
339
340
341
342
322
323
343324
344
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
345366
346367
347
348368
349
369
370
371
350372
351373
352374
353375
354
376
355377
356
357
358
378
359379
360
361
362
380
381
382
383
384
363385
364
365
366
386
387
388
367389
368
369
390
370391
371
372
373
374
375
376
377
378
392
393
394
379395
380
381
382
383
384
396
397
398
385399
386
400
401
387402
388
403
404
405
406
407
408
409
410
411
389412
390413
391
414
392415
393416
394417
395
396
397
398
399
400
418
419
420
421
422
423
401424
402
425
403426
404
405
406
407
408
427
428
429
430
431
432
433
434
409435
410436
411
437
412438
413439
414440
415441
416
417
418
419
420
421
422
442
443
444
445
446
447
448
423449
424
425
426
427
450
451
452
453
454
455
456
428457
429
430
431
432
433
434
435
458
459
460
461
462
463
464
436465
437
438
439
466
467
468
440469
441
442
443
444
445
446
447
470
471
472
473
474
475
476
448477
449
478
450479
451
452
453
454
480
481
482
483
484
455485
456
486
457487
458
459
460
461
462
463
464
465
466
488
489
490
491
492
493
494
495
496
467497
468
498
469499
470
500
471501
472
502
473503
474
475
476
477
478
504
505
506
507
508
479509
480
510
481511
482
483
484
485
512
513
514
515
486516
487
488
517
518
489519
490
491
520
521
492522
493
494
523
524
495525
496
526
497527
498528
499
529
500530
501531
502532
......
509539
510540
511541
512
513
514
515
542
543
544
545
516546
517
518
519
520
521
522
523
524
525
526
527
528
547
548
549
550
551
552
553
554
555
556
557
558
529559
530
531
560
561
562
563
532564
533
565
534566
535
536
537
567
568
569
538570
539
540
541
571
572
573
542574
543
544
575
545576
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
566601
567602
568
603
569604
570605
571606
......
578613
579614
580615
581
582
583
584
616
617
618
619
585620
586
587
588
589
590
591
592
593
594
595
596
597
598
621
622
623
624
625
626
627
628
629
630
631
632
633
599634
600
601
602
603
635
636
637
638
639
640
604641
605
642
606643
607
608
609
644
645
646
610647
611
612
613
648
649
650
614651
615
616
652
617653
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
636675
637676
638
677
639678
640679
641680
......
665704
666705
667706
668
669
670
671
707
708
709
672710
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
691729
692
693
694
695
730
731
732
733
734
696735
697
736
698737
699
700
701
738
739
702740
703
704
705
741
742
706743
707
708
744
709745
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
730763
731764
732
765
733766
734767
735768
......
751784
752785
753786
754
755
756
757
758
759
760
761
762
763
787
764788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
765803
766804
767805
......
879917
880918
881919
882
920
883921
884922
885923
......
903941
904942
905943
906
944
907945
908946
909947
......
936974
937975
938976
939
977
940978
941979
942980
......
961999
9621000
9631001
964
965
966
967
968
969
970
971
972
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
9731014
974
975
1015
1016
9761017
977
978
979
980
1018
1019
1020
1021
9811022
982
983
984
1023
1024
1025
1026
9851027
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
10031045
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
10151057
1016
1058
10171059
1018
1060
10191061
10201062
1021
1063
10221064
10231065
10241066
1025
1026
1027
1028
1029
1067
1068
1069
1070
1071
10301072
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1073
1074
1075
1076
10501077
1051
1052
1053
1054
1055
1056
1057
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
10581103
1059
1060
1061
1062
1063
1104
1105
1106
10641107
1065
1066
1108
1109
1110
1111
1112
1113
1114
10671115
1068
1069
1070
1116
1117
1118
1119
1120
10711121
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1122
1123
1124
10821125
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1126
1127
1128
1129
11051130
1106
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
11071142
1108
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
11091166
1110
1167
1168
1169
1170
1171
11111172
11121173
1113
1174
11141175
1115
1116
11171176
11181177
11191178
11201179
11211180
1122
1123
1124
1181
1182
1183
11251184
1126
1127
1128
1129
1185
1186
1187
1188
1189
1190
11301191
1131
1132
1133
1134
1192
1193
11351194
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
11681250
1169
1170
1251
1252
1253
1254
11711255
11721256
1257
1258
11731259
11741260
1175
1176
1177
11781261
1179
1262
1263
1264
11801265
11811266
1182
1267
11831268
1184
1269
11851270
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1271
11991272
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1273
12111274
1212
1213
1214
1215
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
12161287
1217
1218
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
12191302
1220
1221
1222
1223
1303
1304
1305
1306
12241307
1225
1308
1309
1310
1311
12261312
1227
1228
1229
1230
1313
12311314
1232
1315
1316
1317
1318
12331319
1234
1235
1320
12361321
1237
1238
1239
1240
1322
12411323
1242
1243
1244
1245
1324
1325
1326
1327
12461328
1247
1329
12481330
1249
1331
1332
12501333
1251
1252
1253
1254
1334
1335
1336
1337
12551338
1256
1339
1340
1341
1342
12571343
1258
1259
1260
1261
1262
1263
1344
12641345
1265
1266
1267
1268
1346
12691347
1270
1271
1272
1273
1348
1349
1350
1351
12741352
1275
1276
1277
1353
12781354
1279
1280
1281
1282
1355
1356
1357
1358
1359
1360
12831361
1284
1285
1362
1363
1364
1365
12861366
1287
1367
1368
1369
1370
12881371
1289
1290
1291
1292
1293
1294
1295
1372
1373
1374
12961375
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
13071386
1308
1309
1387
1388
1389
1390
1391
13101392
1311
1312
1313
1314
1315
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
13161404
1317
1318
1405
1406
13191407
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1408
1409
1410
13391411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
13401444
13411445
1342
1343
1446
13441447
13451448
13461449
......
13641467
13651468
13661469
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
13881488
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
14041503
1405
1406
1407
1408
1504
1505
1506
1507
1508
1509
1510
14091511
1410
1411
1412
1413
1512
1513
1514
1515
1516
1517
14141518
1415
1416
1417
1418
1519
1520
1521
1522
14191523
1420
1421
1524
1525
14221526
1423
1424
1527
1528
1529
1530
14251531
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
14361544
14371545
1546
1547
14381548
14391549
14401550
14411551
14421552
1443
1553
14441554
14451555
1446
1447
1556
14481557
1449
1450
1451
1558
14521559
1453
1560
14541561
14551562
1456
1563
14571564
1458
1565
14591566
14601567
1461
1462
1568
14631569
14641570
14651571
1466
1467
1572
14681573
14691574
14701575
14711576
1577
1578
14721579
1473
1474
14751580
14761581
1477
1478
1582
14791583
14801584
14811585
1482
1483
1484
1586
1587
14851588
14861589
14871590
1488
1489
1490
1591
14911592
14921593
14931594
1494
14951595
14961596
14971597
1498
1598
14991599
15001600
15011601
1502
1503
1504
1505
1506
1507
1602
1603
1604
1605
1606
1607
15081608
1509
1510
1511
1512
1609
1610
1611
15131612
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
15331630
1534
1631
15351632
1536
1537
1538
1539
1540
1541
1542
1633
1634
1635
1636
1637
1638
15431639
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1640
15551641
1556
1642
1643
1644
1645
1646
1647
15571648
15581649
1650
1651
15591652
15601653
15611654
......
15651658
15661659
15671660
1661
1662
15681663
15691664
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
15911687
15921688
1689
1690
15931691
15941692
15951693
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
16061705
16071706
1608
1707
1708
1709
16091710
1610
1611
1612
1711
1712
1713
16131714
1614
1715
16151716
1616
1617
1618
1619
1620
1621
1717
1718
1719
1720
1721
1722
1723
1724
16221725
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
16401751
16411752
1753
1754
16421755
16431756
1644
1645
1757
1758
16461759
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
16571770
16581771
1772
1773
16591774
16601775
1661
1662
1663
1664
1776
1777
1778
1779
16651780
1666
1667
1781
1782
16681783
1669
1670
1671
1784
1785
1786
16721787
1673
1674
1675
1676
1677
1788
1789
1790
1791
1792
16781793
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
16911809
1692
1693
1694
1695
1696
1810
1811
1812
1813
1814
1815
1816
1817
1818
16971819
1698
1699
1700
1701
1702
1820
1821
1822
1823
1824
17031825
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1826
1827
1828
1829
1830
1831
17271832
1728
1729
1730
1731
1732
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
17331851
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1852
1853
1854
1855
1856
1857
17441858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
17451872
1746
1747
1748
1749
1750
1751
1873
1874
1875
1876
1877
1878
17521879
17531880
1754
1755
1756
1757
1881
1882
1883
1884
17581885
17591886
1887
1888
17601889
17611890
1762
1763
1764
1891
1892
1893
17651894
1766
1767
1768
1895
1896
1897
17691898
1770
1771
1772
1773
1774
1775
1776
1777
1778
1899
1900
1901
1902
1903
1904
1905
1906
1907
17791908
1780
1781
1782
1783
1909
1910
1911
1912
17841913
17851914
1786
1915
17871916
17881917
17891918
......
18051934
18061935
18071936
1808
1937
18091938
18101939
18111940
18121941
18131942
18141943
1944
18151945
1816
1946
1947
18171948
1949
18181950
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
18411980
18421981
1982
1983
18431984
18441985
18451986
......
18471988
18481989
18491990
1850
1991
18511992
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
18652008
1866
1867
1868
1869
1870
1871
1872
2009
2010
2011
2012
2013
2014
2015
18732016
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
18902037
1891
1892
2038
2039
18932040
18942041
2042
2043
18952044
18962045
1897
1898
2046
2047
18992048
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
19272079
1928
2080
2081
2082
19292083
1930
2084
2085
2086
19312087
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
19462109
19472110
1948
1949
2111
2112
2113
2114
19502115
1951
1952
2116
2117
19532118
1954
1955
1956
1957
1958
1959
1960
1961
1962
2119
2120
2121
2122
2123
19632124
1964
1965
1966
2125
2126
2127
2128
2129
19672130
1968
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
19692141
19702142
2143
2144
19712145
19722146
19732147
1974
2148
19752149
19762150
19772151
1978
1979
1980
1981
1982
1983
2152
2153
2154
2155
2156
2157
2158
19842159
19852160
2161
2162
19862163
19872164
1988
1989
2165
2166
19902167
1991
1992
1993
1994
1995
1996
1997
1998
1999
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
20002180
2001
2002
2003
2004
2005
2006
2181
2182
2183
2184
2185
2186
20072187
20082188
2009
2189
2190
20102191
20112192
2012
2193
20132194
2014
2015
2195
2196
20162197
20172198
2018
2199
2200
20192201
20202202
2021
2203
20222204
2023
2024
2025
2026
2027
2205
20282206
20292207
2208
2209
20302210
20312211
2032
2033
2034
2035
2212
2213
2214
2215
20362216
2037
2038
2039
2040
2041
2217
2218
2219
2220
2221
2222
20422223
2043
2224
20442225
2045
2046
2047
2048
2226
2227
2228
2229
2230
2231
2232
2233
20492234
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
20652252
2066
2253
20672254
20682255
2256
2257
20692258
20702259
20712260
......
20732262
20742263
20752264
2076
2077
2078
2079
2080
2265
2266
2267
2268
2269
2270
20812271
2082
2272
20832273
2084
2085
2086
2087
2274
2275
2276
2277
2278
2279
2280
2281
20882282
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2283
2284
2285
2286
2287
2288
2289
2290
21012291
2102
2292
2293
2294
2295
2296
2297
2298
21032299
21042300
2301
2302
21052303
21062304
2107
2305
21082306
2109
2110
2111
2112
2307
2308
2309
2310
2311
21132312
21142313
2314
2315
21152316
21162317
2117
2318
21182319
2119
2120
2121
2122
2123
2320
2321
2322
2323
2324
21242325
static int getDriveInfo( int biosdev, struct driveInfo *dip )
{
static struct driveInfo cached_di;
int cc;
// Real BIOS devices are 8-bit, so anything above that is for internal use.
// Don't cache ramdisk drive info since it doesn't require several BIOS
// calls and is thus not worth it.
if(biosdev >= 0x100)
{
if(p_get_ramdisk_info != NULL)
cc = (*p_get_ramdisk_info)(biosdev, dip);
else
cc = -1;
if(cc < 0)
{
dip->valid = 0;
return -1;
}
else
return 0;
}
static struct driveInfo cached_di;
int cc;
if ( !cached_di.valid || biosdev != cached_di.biosdev )
{
cc = get_drive_info(biosdev, &cached_di);
if (cc < 0) {
cached_di.valid = 0;
DEBUG_DISK(("get_drive_info returned error\n"));
return (-1); // BIOS call error
// Real BIOS devices are 8-bit, so anything above that is for internal use.
// Don't cache ramdisk drive info since it doesn't require several BIOS
// calls and is thus not worth it.
if (biosdev >= 0x100)
{
if (p_get_ramdisk_info != NULL)
{
cc = (*p_get_ramdisk_info)(biosdev, dip);
}
else
{
cc = -1;
}
if (cc < 0)
{
dip->valid = 0;
return -1;
}
else
{
return 0;
}
}
}
bcopy(&cached_di, dip, sizeof(cached_di));
if (!cached_di.valid || biosdev != cached_di.biosdev)
{
cc = get_drive_info(biosdev, &cached_di);
return 0;
if (cc < 0)
{
cached_di.valid = 0;
DEBUG_DISK(("get_drive_info returned error\n"));
return (-1); // BIOS call error
}
}
bcopy(&cached_di, dip, sizeof(cached_di));
return 0;
}
//==========================================================================
// Maps (E)BIOS return codes to message strings.
struct NamedValue {
unsigned char value;
const char * name;
unsigned char value;
const char * name;
};
//==========================================================================
static const char * getNameForValue( const struct NamedValue * nameTable,
unsigned char value )
{
const struct NamedValue * np;
const struct NamedValue * np;
for ( np = nameTable; np->value; np++)
if (np->value == value)
return np->name;
for ( np = nameTable; np->value; np++)
{
if (np->value == value)
{
return np->name;
}
}
return NULL;
return NULL;
}
#define ECC_CORRECTED_ERR 0x11
static const struct NamedValue bios_errors[] = {
{ 0x10, "Media error" },
{ 0x11, "Corrected ECC error" },
{ 0x20, "Controller or device error" },
{ 0x40, "Seek failed" },
{ 0x80, "Device timeout" },
{ 0xAA, "Drive not ready" },
{ 0x00, 0 }
static const struct NamedValue bios_errors[] =
{
{ 0x10, "Media error" },
{ 0x11, "Corrected ECC error" },
{ 0x20, "Controller or device error" },
{ 0x40, "Seek failed" },
{ 0x80, "Device timeout" },
{ 0xAA, "Drive not ready" },
{ 0x00, 0 }
};
static const char * bios_error(int errnum)
{
static char errorstr[] = "Error 0x00";
const char * errname;
static char errorstr[] = "Error 0x00";
const char * errname;
errname = getNameForValue( bios_errors, errnum );
if ( errname ) return errname;
errname = getNameForValue(bios_errors, errnum);
sprintf(errorstr, "Error 0x%02x", errnum);
return errorstr; // No string, print error code only
if (errname)
{
return errname;
}
sprintf(errorstr, "Error 0x%02x", errnum);
return errorstr; // No string, print error code only
}
//==========================================================================
static int Biosread( int biosdev, unsigned long long secno )
{
static int xbiosdev, xcyl, xhead;
static unsigned int xsec, xnsecs;
struct driveInfo di;
static int xbiosdev, xcyl, xhead;
static unsigned int xsec, xnsecs;
struct driveInfo di;
int rc = -1;
int cyl, head, sec;
int tries = 0;
int bps, divisor;
int rc = -1;
int cyl, head, sec;
int tries = 0;
int bps, divisor;
if (getDriveInfo(biosdev, &di) < 0) {
return -1;
}
if (di.no_emulation) {
/* Always assume 2k block size; BIOS may lie about geometry */
bps = 2048;
} else {
bps = di.di.params.phys_nbps;
if (bps == 0) {
return -1;
}
}
divisor = bps / BPS;
if (getDriveInfo(biosdev, &di) < 0)
{
return -1;
}
DEBUG_DISK(("Biosread dev %x sec %d bps %d\n", biosdev, secno, bps));
if (di.no_emulation)
{
bps = 2048; /* Always assume 2K block size since the BIOS may lie about the geometry */
}
else
{
bps = di.di.params.phys_nbps;
// To read the disk sectors, use EBIOS if we can. Otherwise,
// revert to the standard BIOS calls.
if (bps == 0)
{
return -1;
}
}
if ((biosdev >= kBIOSDevTypeHardDrive) &&
(di.uses_ebios & EBIOS_FIXED_DISK_ACCESS))
{
if (cache_valid &&
(biosdev == xbiosdev) &&
(secno >= xsec) &&
((unsigned int)secno < (xsec + xnsecs)))
{
biosbuf = trackbuf + (BPS * (secno - xsec));
return 0;
}
divisor = bps / BPS;
xnsecs = N_CACHE_SECS;
xsec = (secno / divisor) * divisor;
cache_valid = false;
DEBUG_DISK(("Biosread dev %x sec %d bps %d\n", biosdev, secno, bps));
while ((rc = ebiosread(biosdev, secno / divisor, xnsecs / divisor)) && (++tries < 5))
{
if (rc == ECC_CORRECTED_ERR) {
/* Ignore corrected ECC errors */
rc = 0;
break;
}
error(" EBIOS read error: %s\n", bios_error(rc), rc);
error(" Block 0x%x Sectors %d\n", secno, xnsecs);
sleep(1);
}
}
else
{
/* spc = spt * heads */
int spc = (di.di.params.phys_spt * di.di.params.phys_heads);
cyl = secno / spc;
head = (secno % spc) / di.di.params.phys_spt;
sec = secno % di.di.params.phys_spt;
// To read the disk sectors, use EBIOS if we can. Otherwise,
// revert to the standard BIOS calls.
if (cache_valid &&
(biosdev == xbiosdev) &&
(cyl == xcyl) &&
(head == xhead) &&
((unsigned int)sec >= xsec) &&
((unsigned int)sec < (xsec + xnsecs)))
{
// this sector is in trackbuf cache
biosbuf = trackbuf + (BPS * (sec - xsec));
return 0;
}
if ((biosdev >= kBIOSDevTypeHardDrive) && (di.uses_ebios & EBIOS_FIXED_DISK_ACCESS))
{
if (cache_valid && (biosdev == xbiosdev) && (secno >= xsec) && ((unsigned int)secno < (xsec + xnsecs)))
{
biosbuf = trackbuf + (BPS * (secno - xsec));
return 0;
}
// Cache up to a track worth of sectors, but do not cross a
// track boundary.
xnsecs = N_CACHE_SECS;
xsec = (secno / divisor) * divisor;
cache_valid = false;
xcyl = cyl;
xhead = head;
xsec = sec;
xnsecs = ((unsigned int)(sec + N_CACHE_SECS) > di.di.params.phys_spt) ? (di.di.params.phys_spt - sec) : N_CACHE_SECS;
cache_valid = false;
while ((rc = ebiosread(biosdev, secno / divisor, xnsecs / divisor)) && (++tries < 5))
{
if (rc == ECC_CORRECTED_ERR)
{
rc = 0; /* Ignore corrected ECC errors */
break;
}
while ((rc = biosread(biosdev, cyl, head, sec, xnsecs)) &&
(++tries < 5))
{
if (rc == ECC_CORRECTED_ERR) {
/* Ignore corrected ECC errors */
rc = 0;
break;
}
error(" BIOS read error: %s\n", bios_error(rc), rc);
error(" Block %d, Cyl %d Head %d Sector %d\n",
secno, cyl, head, sec);
sleep(1);
}
}
error(" EBIOS read error: %s\n", bios_error(rc), rc);
error(" Block 0x%x Sectors %d\n", secno, xnsecs);
sleep(1);
}
}
// If the BIOS reported success, mark the sector cache as valid.
else
{
/* spc = spt * heads */
int spc = (di.di.params.phys_spt * di.di.params.phys_heads);
cyl = secno / spc;
head = (secno % spc) / di.di.params.phys_spt;
sec = secno % di.di.params.phys_spt;
if (rc == 0) {
cache_valid = true;
}
biosbuf = trackbuf + (secno % divisor) * BPS;
xbiosdev = biosdev;
spinActivityIndicator(xnsecs);
if (cache_valid && (biosdev == xbiosdev) && (cyl == xcyl) &&
(head == xhead) && ((unsigned int)sec >= xsec) && ((unsigned int)sec < (xsec + xnsecs)))
return rc;
{
// this sector is in trackbuf cache
biosbuf = trackbuf + (BPS * (sec - xsec));
return 0;
}
// Cache up to a track worth of sectors, but do not cross a track boundary.
xcyl = cyl;
xhead = head;
xsec = sec;
xnsecs = ((unsigned int)(sec + N_CACHE_SECS) > di.di.params.phys_spt) ? (di.di.params.phys_spt - sec) : N_CACHE_SECS;
cache_valid = false;
while ((rc = biosread(biosdev, cyl, head, sec, xnsecs)) && (++tries < 5))
{
if (rc == ECC_CORRECTED_ERR)
{
rc = 0; /* Ignore corrected ECC errors */
break;
}
error(" BIOS read error: %s\n", bios_error(rc), rc);
error(" Block %d, Cyl %d Head %d Sector %d\n", secno, cyl, head, sec);
sleep(1);
}
}
// If the BIOS reported success, mark the sector cache as valid.
if (rc == 0)
{
cache_valid = true;
}
biosbuf = trackbuf + (secno % divisor) * BPS;
xbiosdev = biosdev;
spinActivityIndicator(xnsecs);
return rc;
}
//==========================================================================
int testBiosread( int biosdev, unsigned long long secno )
//==============================================================================
int testBiosread(int biosdev, unsigned long long secno)
{
return Biosread(biosdev, secno);
}
//==========================================================================
//==============================================================================
static int readBytes( int biosdev, unsigned long long blkno,
unsigned int byteoff,
unsigned int byteCount, void * buffer )
static int readBytes(int biosdev, unsigned long long blkno, unsigned int byteoff, unsigned int byteCount, void * buffer)
{
// ramdisks require completely different code for reading.
if(p_ramdiskReadBytes != NULL && biosdev >= 0x100)
return (*p_ramdiskReadBytes)(biosdev, blkno, byteoff, byteCount, buffer);
// ramdisks require completely different code for reading.
if(p_ramdiskReadBytes != NULL && biosdev >= 0x100)
{
return (*p_ramdiskReadBytes)(biosdev, blkno, byteoff, byteCount, buffer);
}
char * cbuf = (char *) buffer;
int error;
int copy_len;
char * cbuf = (char *) buffer;
int error;
int copy_len;
DEBUG_DISK(("%s: dev %x block %x [%d] -> 0x%x...", __FUNCTION__,
biosdev, blkno, byteCount, (unsigned)cbuf));
DEBUG_DISK(("%s: dev %x block %x [%d] -> 0x%x...", __FUNCTION__, biosdev, blkno, byteCount, (unsigned)cbuf));
for ( ; byteCount; cbuf += copy_len, blkno++ )
{
error = Biosread( biosdev, blkno );
if ( error )
{
DEBUG_DISK(("error\n"));
return (-1);
}
for (; byteCount; cbuf += copy_len, blkno++)
{
error = Biosread(biosdev, blkno);
copy_len = ((byteCount + byteoff) > BPS) ? (BPS - byteoff) : byteCount;
bcopy( biosbuf + byteoff, cbuf, copy_len );
byteCount -= copy_len;
byteoff = 0;
}
if (error)
{
DEBUG_DISK(("error\n"));
DEBUG_DISK(("done\n"));
return (-1);
}
return 0;
copy_len = ((byteCount + byteoff) > BPS) ? (BPS - byteoff) : byteCount;
bcopy( biosbuf + byteoff, cbuf, copy_len );
byteCount -= copy_len;
byteoff = 0;
}
DEBUG_DISK(("done\n"));
return 0;
}
//==========================================================================
//==============================================================================
static int isExtendedFDiskPartition( const struct fdisk_part * part )
{
static unsigned char extParts[] =
{
0x05, /* Extended */
0x0f, /* Win95 extended */
0x85, /* Linux extended */
};
static unsigned char extParts[] =
{
0x05, /* Extended */
0x0f, /* Win95 extended */
0x85, /* Linux extended */
};
unsigned int i;
unsigned int i;
for (i = 0; i < sizeof(extParts)/sizeof(extParts[0]); i++)
{
if (extParts[i] == part->systid) return 1;
}
return 0;
for (i = 0; i < sizeof(extParts)/sizeof(extParts[0]); i++)
{
if (extParts[i] == part->systid)
{
return 1;
}
}
return 0;
}
//==========================================================================
//==============================================================================
static int getNextFDiskPartition( int biosdev, int * partno,
const struct fdisk_part ** outPart )
{
static int sBiosdev = -1;
static int sNextPartNo;
static unsigned int sFirstBase;
static unsigned int sExtBase;
static unsigned int sExtDepth;
static struct fdisk_part * sExtPart;
struct fdisk_part * part;
static int sBiosdev = -1;
static int sNextPartNo;
static unsigned int sFirstBase;
static unsigned int sExtBase;
static unsigned int sExtDepth;
static struct fdisk_part * sExtPart;
struct fdisk_part * part;
if ( sBiosdev != biosdev || *partno < 0 )
{
// Fetch MBR.
if ( readBootSector( biosdev, DISK_BLK0, 0 ) ) return 0;
if ( sBiosdev != biosdev || *partno < 0 )
{
// Fetch MBR.
if ( readBootSector( biosdev, DISK_BLK0, 0 ) )
{
return 0;
}
sBiosdev = biosdev;
sNextPartNo = 0;
sFirstBase = 0;
sExtBase = 0;
sExtDepth = 0;
sExtPart = NULL;
}
sBiosdev = biosdev;
sNextPartNo = 0;
sFirstBase = 0;
sExtBase = 0;
sExtDepth = 0;
sExtPart = NULL;
}
while (1)
{
part = NULL;
while (1)
{
part = NULL;
if ( sNextPartNo < FDISK_NPART )
{
part = (struct fdisk_part *) gBootSector->parts[sNextPartNo];
}
else if ( sExtPart )
{
unsigned int blkno = sExtPart->relsect + sFirstBase;
if ( sNextPartNo < FDISK_NPART )
{
part = (struct fdisk_part *) gBootSector->parts[sNextPartNo];
}
else if ( sExtPart )
{
unsigned int blkno = sExtPart->relsect + sFirstBase;
// Save the block offset of the first extended partition.
// Save the block offset of the first extended partition.
if (sExtDepth == 0) {
sFirstBase = blkno;
}
sExtBase = blkno;
if (sExtDepth == 0)
{
sFirstBase = blkno;
}
sExtBase = blkno;
// Load extended partition table.
// Load extended partition table.
if ( readBootSector( biosdev, blkno, 0 ) == 0 )
{
sNextPartNo = 0;
sExtDepth++;
sExtPart = NULL;
continue;
}
// Fall through to part == NULL
}
if ( readBootSector( biosdev, blkno, 0 ) == 0 )
{
sNextPartNo = 0;
sExtDepth++;
sExtPart = NULL;
continue;
}
// Fall through to part == NULL
}
if ( part == NULL ) break; // Reached end of partition chain.
if ( part == NULL ) break; // Reached end of partition chain.
// Advance to next partition number.
// Advance to next partition number.
sNextPartNo++;
sNextPartNo++;
if ( isExtendedFDiskPartition(part) )
{
sExtPart = part;
continue;
}
if ( isExtendedFDiskPartition(part) )
{
sExtPart = part;
continue;
}
// Skip empty slots.
// Skip empty slots.
if ( part->systid == 0x00 )
{
continue;
}
if ( part->systid == 0x00 )
{
continue;
}
// Change relative offset to an absolute offset.
part->relsect += sExtBase;
// Change relative offset to an absolute offset.
part->relsect += sExtBase;
*outPart = part;
*partno = sExtDepth ? (int)(sExtDepth + FDISK_NPART) : sNextPartNo;
*outPart = part;
*partno = sExtDepth ? (int)(sExtDepth + FDISK_NPART) : sNextPartNo;
break;
}
break;
}
return (part != NULL);
return (part != NULL);
}
//==========================================================================
//==============================================================================
static BVRef newFDiskBVRef( int biosdev, int partno, unsigned int blkoff,
const struct fdisk_part * part,
BVFree bvFreeFunc,
int probe, int type, unsigned int bvrFlags )
{
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr )
{
bzero(bvr, sizeof(*bvr));
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr )
{
bzero(bvr, sizeof(*bvr));
bvr->biosdev = biosdev;
bvr->part_no = partno;
bvr->part_boff = blkoff;
bvr->part_type = part->systid;
bvr->fs_loadfile = loadFunc;
bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
bvr->fs_getfileblock= getBlockFunc;
bvr->fs_getuuid = getUUIDFunc;
bvr->description = getDescriptionFunc;
bvr->type = type;
bvr->bv_free = bvFreeFunc;
bvr->biosdev = biosdev;
bvr->part_no = partno;
bvr->part_boff = blkoff;
bvr->part_type = part->systid;
bvr->fs_loadfile = loadFunc;
bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
bvr->fs_getfileblock= getBlockFunc;
bvr->fs_getuuid = getUUIDFunc;
bvr->description = getDescriptionFunc;
bvr->type = type;
bvr->bv_free = bvFreeFunc;
if ((part->bootid & FDISK_ACTIVE) && (part->systid == FDISK_HFS))
bvr->flags |= kBVFlagPrimary;
if ((part->bootid & FDISK_ACTIVE) && (part->systid == FDISK_HFS))
{
bvr->flags |= kBVFlagPrimary;
}
// Probe the filesystem.
// Probe the filesystem.
if ( initFunc )
{
bvr->flags |= kBVFlagNativeBoot;
if ( initFunc )
{
bvr->flags |= kBVFlagNativeBoot;
if ( probe && initFunc( bvr ) != 0 )
{
// filesystem probe failed.
if ( probe && initFunc( bvr ) != 0 )
{
// filesystem probe failed.
DEBUG_DISK(("%s: failed probe on dev %x part %d\n",
__FUNCTION__, biosdev, partno));
DEBUG_DISK(("%s: failed probe on dev %x part %d\n", __FUNCTION__, biosdev, partno));
(*bvr->bv_free)(bvr);
bvr = NULL;
}
if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
{
bvr->flags |= kBVFlagBootable;
}
}
else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
{
bvr->flags |= kBVFlagForeignBoot;
}
else
{
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
if (bvr) bvr->flags |= bvrFlags;
return bvr;
(*bvr->bv_free)(bvr);
bvr = NULL;
}
if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
{
bvr->flags |= kBVFlagBootable;
}
}
else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
{
bvr->flags |= kBVFlagForeignBoot;
}
else
{
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
if (bvr) bvr->flags |= bvrFlags;
{
return bvr;
}
}
//==========================================================================
//==============================================================================
BVRef newAPMBVRef( int biosdev, int partno, unsigned int blkoff,
const DPME * part,
BVFree bvFreeFunc,
int probe, int type, unsigned int bvrFlags )
{
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr )
{
bzero(bvr, sizeof(*bvr));
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr )
{
bzero(bvr, sizeof(*bvr));
bvr->biosdev = biosdev;
bvr->part_no = partno;
bvr->part_boff = blkoff;
bvr->fs_loadfile = loadFunc;
bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
bvr->fs_getfileblock= getBlockFunc;
bvr->fs_getuuid = getUUIDFunc;
bvr->description = getDescriptionFunc;
bvr->type = type;
bvr->bv_free = bvFreeFunc;
strlcpy(bvr->name, part->dpme_name, DPISTRLEN);
strlcpy(bvr->type_name, part->dpme_type, DPISTRLEN);
bvr->biosdev = biosdev;
bvr->part_no = partno;
bvr->part_boff = blkoff;
bvr->fs_loadfile = loadFunc;
bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
bvr->fs_getfileblock= getBlockFunc;
bvr->fs_getuuid = getUUIDFunc;
bvr->description = getDescriptionFunc;
bvr->type = type;
bvr->bv_free = bvFreeFunc;
strlcpy(bvr->name, part->dpme_name, DPISTRLEN);
strlcpy(bvr->type_name, part->dpme_type, DPISTRLEN);
/*
if ( part->bootid & FDISK_ACTIVE )
bvr->flags |= kBVFlagPrimary;
*/
/*
if ( part->bootid & FDISK_ACTIVE )
{
bvr->flags |= kBVFlagPrimary;
}
*/
// Probe the filesystem.
// Probe the filesystem.
if ( initFunc )
{
bvr->flags |= kBVFlagNativeBoot | kBVFlagBootable | kBVFlagSystemVolume;
if ( initFunc )
{
bvr->flags |= kBVFlagNativeBoot | kBVFlagBootable | kBVFlagSystemVolume;
if ( probe && initFunc( bvr ) != 0 )
{
// filesystem probe failed.
if ( probe && initFunc( bvr ) != 0 )
{
// filesystem probe failed.
DEBUG_DISK(("%s: failed probe on dev %x part %d\n",
__FUNCTION__, biosdev, partno));
DEBUG_DISK(("%s: failed probe on dev %x part %d\n", __FUNCTION__, biosdev, partno));
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
/*
else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
{
bvr->flags |= kBVFlagForeignBoot;
}
*/
else
{
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
if (bvr) bvr->flags |= bvrFlags;
return bvr;
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
/*
else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
{
bvr->flags |= kBVFlagForeignBoot;
}
*/
else
{
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
if (bvr)
{
bvr->flags |= bvrFlags;
}
return bvr;
}
//==========================================================================
//==============================================================================
// GUID's in LE form:
// HFS+ partition - 48465300-0000-11AA-AA11-00306543ECAC
BVFree bvFreeFunc,
int probe, int type, unsigned int bvrFlags )
{
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr )
{
bzero(bvr, sizeof(*bvr));
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr ) {
bzero(bvr, sizeof(*bvr));
bvr->biosdev = biosdev;
bvr->part_no = partno;
bvr->part_boff = blkoff;
bvr->fs_loadfile = loadFunc;
bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
bvr->fs_getfileblock= getBlockFunc;
bvr->fs_getuuid = getUUIDFunc;
bvr->description = getDescriptionFunc;
bvr->type = type;
bvr->bv_free = bvFreeFunc;
// FIXME: UCS-2 -> UTF-8 the name
strlcpy(bvr->name, "----", DPISTRLEN);
if ( (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)part->ent_type) == 0) ||
(efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const*)part->ent_type) == 0) )
strlcpy(bvr->type_name, "GPT HFS+", DPISTRLEN);
else
strlcpy(bvr->type_name, "GPT Unknown", DPISTRLEN);
bvr->biosdev = biosdev;
bvr->part_no = partno;
bvr->part_boff = blkoff;
bvr->fs_loadfile = loadFunc;
bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
bvr->fs_getfileblock= getBlockFunc;
bvr->fs_getuuid = getUUIDFunc;
bvr->description = getDescriptionFunc;
bvr->type = type;
bvr->bv_free = bvFreeFunc;
// FIXME: UCS-2 -> UTF-8 the name
strlcpy(bvr->name, "----", DPISTRLEN);
if ( (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)part->ent_type) == 0) || (efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const*)part->ent_type) == 0) ) {
strlcpy(bvr->type_name, "GPT HFS+", DPISTRLEN);
} else {
strlcpy(bvr->type_name, "GPT Unknown", DPISTRLEN);
}
/*
if ( part->bootid & FDISK_ACTIVE )
bvr->flags |= kBVFlagPrimary;
*/
/*
if ( part->bootid & FDISK_ACTIVE ) {
bvr->flags |= kBVFlagPrimary;
}
*/
// Probe the filesystem.
// Probe the filesystem.
if ( initFunc )
{
bvr->flags |= kBVFlagNativeBoot;
if ( initFunc ) {
bvr->flags |= kBVFlagNativeBoot;
if ( probe && initFunc( bvr ) != 0 )
{
// filesystem probe failed.
if ( probe && initFunc( bvr ) != 0 ) {
// filesystem probe failed.
DEBUG_DISK(("%s: failed probe on dev %x part %d\n",
__FUNCTION__, biosdev, partno));
DEBUG_DISK(("%s: failed probe on dev %x part %d\n", __FUNCTION__, biosdev, partno));
(*bvr->bv_free)(bvr);
bvr = NULL;
}
if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
{
bvr->flags |= kBVFlagBootable;
}
}
else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
{
bvr->flags |= kBVFlagForeignBoot;
}
else
{
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
if (bvr) bvr->flags |= bvrFlags;
return bvr;
(*bvr->bv_free)(bvr);
bvr = NULL;
}
if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 ) {
bvr->flags |= kBVFlagBootable;
}
} else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 ) {
bvr->flags |= kBVFlagForeignBoot;
} else {
(*bvr->bv_free)(bvr);
bvr = NULL;
}
}
if (bvr) {
bvr->flags |= bvrFlags;
}
return bvr;
}
//==========================================================================
//==============================================================================
/* A note on partition numbers:
* IOKit makes the primary partitions numbers 1-4, and then
struct driveInfo di;
boot_drive_info_t *dp;
/* Initialize disk info */
if (getDriveInfo(biosdev, &di) != 0) {
return NULL;
}
dp = &di.di;
spc = (dp->params.phys_spt * dp->params.phys_heads);
if (spc == 0) {
/* This is probably a CD-ROM; punt on the geometry. */
spc = 1;
}
/* Initialize disk info */
if (getDriveInfo(biosdev, &di) != 0)
{
return NULL;
}
dp = &di.di;
spc = (dp->params.phys_spt * dp->params.phys_heads);
if (spc == 0)
{
/* This is probably a CD-ROM; punt on the geometry. */
spc = 1;
}
do {
// Create a new mapping.
0,
kBIOSDevTypeHardDrive, 0);
break;
case FDISK_NTFS:
bvr = newFDiskBVRef(
biosdev, partno,
(BVFree)free,
0, kBIOSDevTypeHardDrive, 0);
break;
case FDISK_BEFS:
bvr = newFDiskBVRef(
biosdev, partno,
(BVFree)free,
0, kBIOSDevTypeHardDrive, 0);
break;
default:
bvr = newFDiskBVRef(
biosdev, partno,
// Booting from a CD with an UFS filesystem embedded
// in a booter partition.
if ( booterUFS )
{
if ( map->bvrcnt == 0 )
{
map->bvr = booterUFS;
map->bvrcnt++;
}
else free( booterUFS );
}
if ( booterUFS )
{
if ( map->bvrcnt == 0 )
{
map->bvr = booterUFS;
map->bvrcnt++;
}
else
{
free( booterUFS );
}
}
#endif
}
} while (0);
}
} while (0);
/*
* If no FDisk partition, then we will check for
* an Apple partition map elsewhere.
*/
/*
* If no FDisk partition, then we will check for
* an Apple partition map elsewhere.
*/
#if UNUSED
if (map->bvrcnt == 0) {
static struct fdisk_part cdpart;
cdpart.systid = 0xCD;
if (map->bvrcnt == 0)
{
static struct fdisk_part cdpart;
cdpart.systid = 0xCD;
/* Let's try assuming we are on a hybrid HFS/ISO9660 CD. */
bvr = newFDiskBVRef(
biosdev, 0,
0,
&cdpart,
HFSInitPartition,
HFSLoadFile,
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
HFSGetUUID,
0,
kBIOSDevTypeHardDrive);
bvr->next = map->bvr;
map->bvr = bvr;
map->bvrcnt++;
}
/* Let's try assuming we are on a hybrid HFS/ISO9660 CD. */
bvr = newFDiskBVRef(
biosdev, 0,
0,
&cdpart,
HFSInitPartition,
HFSLoadFile,
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
HFSGetUUID,
0,
kBIOSDevTypeHardDrive);
bvr->next = map->bvr;
map->bvr = bvr;
map->bvrcnt++;
}
#endif
// Actually this should always be true given the above code
if(map == gDiskBVMap)
{
// Don't leave a null map in the chain
if(map->bvrcnt == 0 && map->bvr == NULL)
{
gDiskBVMap = map->next;
free(map);
map = NULL;
}
}
// Actually this should always be true given the above code
if(map == gDiskBVMap)
{
// Don't leave a null map in the chain
if(map->bvrcnt == 0 && map->bvr == NULL)
{
gDiskBVMap = map->next;
free(map);
map = NULL;
}
}
if (countPtr) *countPtr = map ? map->bvrcnt : 0;
if (countPtr) *countPtr = map ? map->bvrcnt : 0;
return map ? map->bvr : NULL;
return map ? map->bvr : NULL;
}
//==========================================================================
//==============================================================================
static BVRef diskScanAPMBootVolumes( int biosdev, int * countPtr )
{
struct DiskBVMap * map;
struct Block0 *block0_p;
unsigned int blksize;
unsigned int factor;
void *buffer = malloc(BPS);
struct DiskBVMap * map;
struct Block0 *block0_p;
unsigned int blksize;
unsigned int factor;
void *buffer = malloc(BPS);
/* Check for alternate block size */
if (readBytes( biosdev, 0, 0, BPS, buffer ) != 0) {
return NULL;
}
block0_p = buffer;
if (OSSwapBigToHostInt16(block0_p->sbSig) == BLOCK0_SIGNATURE) {
blksize = OSSwapBigToHostInt16(block0_p->sbBlkSize);
if (blksize != BPS) {
free(buffer);
buffer = malloc(blksize);
}
factor = blksize / BPS;
} else {
blksize = BPS;
factor = 1;
}
do {
// Create a new mapping.
if (!buffer)
{
return NULL;
}
map = (struct DiskBVMap *) malloc( sizeof(*map) );
if ( map )
{
int error;
DPME *dpme_p = (DPME *)buffer;
UInt32 i, npart = UINT_MAX;
BVRef bvr;
/* Check for alternate block size */
if (readBytes( biosdev, 0, 0, BPS, buffer ) != 0)
{
return NULL;
}
block0_p = buffer;
if (OSSwapBigToHostInt16(block0_p->sbSig) == BLOCK0_SIGNATURE)
{
blksize = OSSwapBigToHostInt16(block0_p->sbBlkSize);
if (blksize != BPS)
{
free(buffer);
buffer = malloc(blksize);
if (!buffer)
{
return NULL;
}
}
factor = blksize / BPS;
}
else
{
blksize = BPS;
factor = 1;
}
map->biosdev = biosdev;
map->bvr = NULL;
map->bvrcnt = 0;
map->next = gDiskBVMap;
gDiskBVMap = map;
do
{
// Create a new mapping.
for (i=0; i<npart; i++) {
error = readBytes( biosdev, (kAPMSector + i) * factor, 0, blksize, buffer );
map = (struct DiskBVMap *) malloc( sizeof(*map) );
if ( map )
{
int error;
DPME *dpme_p = (DPME *)buffer;
UInt32 i, npart = UINT_MAX;
BVRef bvr;
if (error || OSSwapBigToHostInt16(dpme_p->dpme_signature) != DPME_SIGNATURE) {
break;
}
map->biosdev = biosdev;
map->bvr = NULL;
map->bvrcnt = 0;
map->next = gDiskBVMap;
gDiskBVMap = map;
if (i==0) {
npart = OSSwapBigToHostInt32(dpme_p->dpme_map_entries);
}
/*
printf("name = %s, %s%s %d -> %d [%d -> %d] {%d}\n",
dpme.dpme_name, dpme.dpme_type, (dpme.dpme_flags & DPME_FLAGS_BOOTABLE) ? "(bootable)" : "",
dpme.dpme_pblock_start, dpme.dpme_pblocks,
dpme.dpme_lblock_start, dpme.dpme_lblocks,
dpme.dpme_boot_block);
*/
for (i=0; i<npart; i++)
{
error = readBytes( biosdev, (kAPMSector + i) * factor, 0, blksize, buffer );
if (strcmp(dpme_p->dpme_type, "Apple_HFS") == 0) {
bvr = newAPMBVRef(biosdev,
i,
OSSwapBigToHostInt32(dpme_p->dpme_pblock_start) * factor,
dpme_p,
HFSInitPartition,
HFSLoadFile,
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
HFSGetUUID,
HFSGetDescription,
HFSFree,
0,
kBIOSDevTypeHardDrive, 0);
bvr->next = map->bvr;
map->bvr = bvr;
map->bvrcnt++;
}
}
}
} while (0);
if (error || OSSwapBigToHostInt16(dpme_p->dpme_signature) != DPME_SIGNATURE)
{
break;
}
free(buffer);
if (i==0)
{
npart = OSSwapBigToHostInt32(dpme_p->dpme_map_entries);
}
/*
printf("name = %s, %s%s %d -> %d [%d -> %d] {%d}\n",
dpme.dpme_name, dpme.dpme_type, (dpme.dpme_flags & DPME_FLAGS_BOOTABLE) ? "(bootable)" : "",
dpme.dpme_pblock_start, dpme.dpme_pblocks,
dpme.dpme_lblock_start, dpme.dpme_lblocks,
dpme.dpme_boot_block);
*/
if (countPtr) *countPtr = map ? map->bvrcnt : 0;
if (strcmp(dpme_p->dpme_type, "Apple_HFS") == 0)
{
bvr = newAPMBVRef(biosdev,
i,
OSSwapBigToHostInt32(dpme_p->dpme_pblock_start) * factor,
dpme_p,
HFSInitPartition,
HFSLoadFile,
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
HFSGetUUID,
HFSGetDescription,
HFSFree,
0,
kBIOSDevTypeHardDrive, 0);
bvr->next = map->bvr;
map->bvr = bvr;
map->bvrcnt++;
}
}
}
} while (0);
return map ? map->bvr : NULL;
free(buffer);
if (countPtr) *countPtr = map ? map->bvrcnt : 0;
return map ? map->bvr : NULL;
}
//==========================================================================
//==============================================================================
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
* Trying to figure out the filsystem type of a given partition.
*/
static int probeFileSystem(int biosdev, unsigned int blkoff)
{
// detected filesystem type;
int result = -1;
int fatbits;
// detected filesystem type;
int result = -1;
int fatbits;
// Allocating buffer for 4 sectors.
const void * probeBuffer = malloc(PROBEFS_SIZE);
if (probeBuffer == NULL)
goto exit;
// Allocating buffer for 4 sectors.
const void * probeBuffer = malloc(PROBEFS_SIZE);
if (probeBuffer == NULL)
{
goto exit;
}
// Reading first 4 sectors of current partition
int error = readBytes(biosdev, blkoff, 0, PROBEFS_SIZE, (void *)probeBuffer);
if (error)
goto exit;
// Reading first 4 sectors of current partition
int error = readBytes(biosdev, blkoff, 0, PROBEFS_SIZE, (void *)probeBuffer);
if (HFSProbe(probeBuffer))
result = FDISK_HFS;
else if (EX2Probe(probeBuffer))
result = FDISK_LINUX;
else if (FreeBSDProbe(probeBuffer))
result = FDISK_FREEBSD;
else if (OpenBSDProbe(probeBuffer))
result = FDISK_OPENBSD;
else if (NTFSProbe(probeBuffer))
result = FDISK_NTFS;
else if (BeFSProbe(probeBuffer))
result = FDISK_BEFS;
else if ( (fatbits = MSDOSProbe(probeBuffer)) )
{
switch (fatbits)
{
case 32:
default:
result = FDISK_FAT32;
break;
case 16:
result = FDISK_DOS16B;
break;
case 12:
result = FDISK_DOS12;
break;
}
}
else
// Couldn't detect filesystem type
result = 0;
if (error)
{
goto exit;
}
if (HFSProbe(probeBuffer))
{
result = FDISK_HFS;
}
else if (EX2Probe(probeBuffer))
{
result = FDISK_LINUX;
}
else if (FreeBSDProbe(probeBuffer))
{
result = FDISK_FREEBSD;
}
else if (OpenBSDProbe(probeBuffer))
{
result = FDISK_OPENBSD;
}
else if (BeFSProbe(probeBuffer))
{
result = FDISK_BEFS;
}
else if (NTFSProbe(probeBuffer))
{
result = FDISK_NTFS;
}
else if ( (fatbits = MSDOSProbe(probeBuffer)) )
{
switch (fatbits)
{
case 32:
default:
result = FDISK_FAT32;
break;
case 16:
result = FDISK_DOS16B;
break;
case 12:
result = FDISK_DOS12;
break;
}
}
else
{
// Couldn't detect filesystem type
result = 0;
}
exit:
if (probeBuffer != NULL) free((void *)probeBuffer);
return result;
if (probeBuffer != NULL) free((void *)probeBuffer);
{
return result;
}
}
//==============================================================================
static bool isPartitionUsed(gpt_ent * partition)
{
//
// Ask whether the given partition is used.
//
return efi_guid_is_null((EFI_GUID const*)partition->ent_type) ? false : true;
// Ask whether the given partition is used.
return efi_guid_is_null((EFI_GUID const*)partition->ent_type) ? false : true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//==============================================================================
static BVRef diskScanGPTBootVolumes( int biosdev, int * countPtr )
static BVRef diskScanGPTBootVolumes(int biosdev, int * countPtr)
{
struct DiskBVMap * map = NULL;
void *buffer = malloc(BPS);
int error;
if ( (error = readBytes( biosdev, /*secno*/0, 0, BPS, buffer )) != 0) {
verbose("Failed to read boot sector from BIOS device %02xh. Error=%d\n", biosdev, error);
goto scanErr;
}
struct REAL_disk_blk0 *fdiskMap = buffer;
if ( OSSwapLittleToHostInt16(fdiskMap->signature) != DISK_SIGNATURE )
{
verbose("Failed to find boot signature on BIOS device %02xh\n", biosdev);
goto scanErr;
}
struct DiskBVMap *map = NULL;
int fdiskID = 0;
unsigned index;
for ( index = 0; index < FDISK_NPART; index++ )
{
if ( fdiskMap->parts[index].systid )
{
if ( fdiskMap->parts[index].systid == 0xEE )
{
// Fail if two 0xEE partitions are present which
// means the FDISK code will wind up parsing it.
if ( fdiskID ) goto scanErr;
void *buffer = malloc(BPS);
fdiskID = index + 1;
}
}
}
int error;
if ( (error = readBytes( biosdev, /*secno*/0, 0, BPS, buffer )) != 0)
{
verbose("Failed to read boot sector from BIOS device %02xh. Error=%d\n", biosdev, error);
goto scanErr;
}
struct REAL_disk_blk0 *fdiskMap = buffer;
if ( OSSwapLittleToHostInt16(fdiskMap->signature) != DISK_SIGNATURE )
{
verbose("Failed to find boot signature on BIOS device %02xh\n", biosdev);
goto scanErr;
}
if ( fdiskID == 0 ) goto scanErr;
verbose("Attempting to read GPT\n");
int fdiskID = 0;
unsigned index;
for ( index = 0; index < FDISK_NPART; index++ )
{
if ( fdiskMap->parts[index].systid )
{
if ( fdiskMap->parts[index].systid == 0xEE )
{
// Fail if two 0xEE partitions are present which
// means the FDISK code will wind up parsing it.
if ( fdiskID )
{
goto scanErr;
}
if(readBytes(biosdev, 1, 0, BPS, buffer) != 0)
goto scanErr;
gpt_hdr *headerMap = buffer;
fdiskID = index + 1;
}
}
}
// Determine whether the partition header signature is present.
if ( fdiskID == 0 )
{
goto scanErr;
}
if ( memcmp(headerMap->hdr_sig, GPT_HDR_SIG, strlen(GPT_HDR_SIG)) )
{
goto scanErr;
}
verbose("Attempting to read GPT\n");
// Determine whether the partition header size is valid.
if(readBytes(biosdev, 1, 0, BPS, buffer) != 0)
{
goto scanErr;
}
UInt32 headerCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_self);
UInt32 headerSize = OSSwapLittleToHostInt32(headerMap->hdr_size);
gpt_hdr *headerMap = buffer;
if ( headerSize < offsetof(gpt_hdr, padding) )
{
goto scanErr;
}
// Determine whether the partition header signature is present.
if ( headerSize > BPS )
{
goto scanErr;
}
if ( memcmp(headerMap->hdr_sig, GPT_HDR_SIG, strlen(GPT_HDR_SIG)) )
{
goto scanErr;
}
// Determine whether the partition header checksum is valid.
// Determine whether the partition header size is valid.
headerMap->hdr_crc_self = 0;
UInt32 headerCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_self);
UInt32 headerSize = OSSwapLittleToHostInt32(headerMap->hdr_size);
if ( crc32(0, headerMap, headerSize) != headerCheck )
{
goto scanErr;
}
if ( headerSize < offsetof(gpt_hdr, padding) )
{
goto scanErr;
}
// Determine whether the partition entry size is valid.
if ( headerSize > BPS )
{
goto scanErr;
}
UInt64 gptBlock = 0;
UInt32 gptCheck = 0;
UInt32 gptCount = 0;
UInt32 gptID = 0;
gpt_ent * gptMap = 0;
UInt32 gptSize = 0;
// Determine whether the partition header checksum is valid.
gptBlock = OSSwapLittleToHostInt64(headerMap->hdr_lba_table);
gptCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_table);
gptCount = OSSwapLittleToHostInt32(headerMap->hdr_entries);
gptSize = OSSwapLittleToHostInt32(headerMap->hdr_entsz);
headerMap->hdr_crc_self = 0;
if ( gptSize < sizeof(gpt_ent) )
{
goto scanErr;
}
if ( crc32(0, headerMap, headerSize) != headerCheck )
{
goto scanErr;
}
// Allocate a buffer large enough to hold one map, rounded to a media block.
free(buffer);
buffer = NULL;
// Determine whether the partition entry size is valid.
UInt32 bufferSize = IORound(gptCount * gptSize, BPS);
if(bufferSize == 0)
goto scanErr;
buffer = malloc(bufferSize);
UInt64 gptBlock = 0;
UInt32 gptCheck = 0;
UInt32 gptCount = 0;
UInt32 gptID = 0;
gpt_ent * gptMap = 0;
UInt32 gptSize = 0;
if(readBytes(biosdev, gptBlock, 0, bufferSize, buffer) != 0)
goto scanErr;
gptBlock = OSSwapLittleToHostInt64(headerMap->hdr_lba_table);
gptCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_table);
gptCount = OSSwapLittleToHostInt32(headerMap->hdr_entries);
gptSize = OSSwapLittleToHostInt32(headerMap->hdr_entsz);
verbose("Read GPT\n");
if ( gptSize < sizeof(gpt_ent) )
{
goto scanErr;
}
// Allocate a new map for this BIOS device and insert it into the chain
map = malloc(sizeof(*map));
map->biosdev = biosdev;
map->bvr = NULL;
map->bvrcnt = 0;
map->next = gDiskBVMap;
gDiskBVMap = map;
// Allocate a buffer large enough to hold one map, rounded to a media block.
free(buffer);
buffer = NULL;
// fdisk like partition type id.
int fsType = 0;
for(gptID = 1; gptID <= gptCount; ++gptID)
{
BVRef bvr = NULL;
unsigned int bvrFlags = 0;
// size on disk can be larger than sizeof(gpt_ent)
gptMap = (gpt_ent *) ( buffer + ( (gptID - 1) * gptSize) );
UInt32 bufferSize = IORound(gptCount * gptSize, BPS);
if (bufferSize == 0)
{
goto scanErr;
}
buffer = malloc(bufferSize);
if (!buffer)
{
goto scanErr;
}
// NOTE: EFI_GUID's are in LE and we know we're on an x86.
// The IOGUIDPartitionScheme.cpp code uses byte-based UUIDs, we don't.
if (readBytes(biosdev, gptBlock, 0, bufferSize, buffer) != 0)
{
goto scanErr;
}
verbose("Read GPT\n");
if (isPartitionUsed(gptMap))
{
char stringuuid[100];
efi_guid_unparse_upper((EFI_GUID*)gptMap->ent_type, stringuuid);
verbose("Reading GPT partition %d, type %s\n", gptID, stringuuid);
// Allocate a new map for this BIOS device and insert it into the chain
map = malloc(sizeof(*map));
if (!map)
{
goto scanErr;
}
map->biosdev = biosdev;
map->bvr = NULL;
map->bvrcnt = 0;
map->next = gDiskBVMap;
gDiskBVMap = map;
// Getting fdisk like partition type.
fsType = probeFileSystem(biosdev, gptMap->ent_lba_start);
// fdisk like partition type id.
int fsType = 0;
if ( (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ||
(efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) )
{
bvrFlags = (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ? kBVFlagBooter : 0;
bvr = newGPTBVRef(biosdev,
gptID,
gptMap->ent_lba_start,
gptMap,
HFSInitPartition,
HFSLoadFile,
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
HFSGetUUID,
HFSGetDescription,
HFSFree,
0,
kBIOSDevTypeHardDrive, bvrFlags);
}
for(gptID = 1; gptID <= gptCount; ++gptID) {
BVRef bvr = NULL;
unsigned int bvrFlags = 0;
// size on disk can be larger than sizeof(gpt_ent)
gptMap = (gpt_ent *) ( buffer + ( (gptID - 1) * gptSize) );
// NOTE: EFI_GUID's are in LE and we know we're on an x86.
// The IOGUIDPartitionScheme.cpp code uses byte-based UUIDs, we don't.
if (isPartitionUsed(gptMap)) {
char stringuuid[100];
efi_guid_unparse_upper((EFI_GUID*)gptMap->ent_type, stringuuid);
verbose("Reading GPT partition %d, type %s\n", gptID, stringuuid);
// Getting fdisk like partition type.
fsType = probeFileSystem(biosdev, gptMap->ent_lba_start);
if ( (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) || (efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ) {
bvrFlags = (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ? kBVFlagBooter : 0;
bvr = newGPTBVRef(biosdev,
gptID,
gptMap->ent_lba_start,
gptMap,
HFSInitPartition,
HFSLoadFile,
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
HFSGetUUID,
HFSGetDescription,
HFSFree,
0,
kBIOSDevTypeHardDrive, bvrFlags);
}
// zef - foreign OS support
if ( (efi_guid_compare(&GPT_BASICDATA_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ||
(efi_guid_compare(&GPT_BASICDATA2_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) )
{
(efi_guid_compare(&GPT_BASICDATA2_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ) {
switch (fsType)
{
case FDISK_NTFS:
}
// turbo - save our booter partition
// zef - only on original boot device
if ( (efi_guid_compare(&GPT_EFISYS_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) )
{
switch (fsType)
{
case FDISK_HFS:
if (readBootSector( biosdev, gptMap->ent_lba_start, (void *)0x7e00 ) == 0)
{
bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap,
HFSInitPartition,
HFSLoadFile,
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
HFSGetUUID,
HFSGetDescription,
HFSFree,
0, kBIOSDevTypeHardDrive, kBVFlagEFISystem);
}
break;
// turbo - save our booter partition
// zef - only on original boot device
if ( (efi_guid_compare(&GPT_EFISYS_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ) {
switch (fsType) {
case FDISK_HFS:
if (readBootSector( biosdev, gptMap->ent_lba_start, (void *)0x7e00 ) == 0) {
bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap,
HFSInitPartition,
HFSLoadFile,
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
HFSGetUUID,
HFSGetDescription,
HFSFree,
0, kBIOSDevTypeHardDrive, kBVFlagEFISystem);
}
break;
case FDISK_FAT32:
if (testFAT32EFIBootSector( biosdev, gptMap->ent_lba_start, (void *)0x7e00 ) == 0)
{
bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap,
MSDOSInitPartition,
MSDOSLoadFile,
MSDOSReadFile,
MSDOSGetDirEntry,
MSDOSGetFileBlock,
MSDOSGetUUID,
MSDOSGetDescription,
MSDOSFree,
0, kBIOSDevTypeHardDrive, kBVFlagEFISystem);
}
break;
case FDISK_FAT32:
if (testFAT32EFIBootSector( biosdev, gptMap->ent_lba_start, (void *)0x7e00 ) == 0) {
bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap,
MSDOSInitPartition,
MSDOSLoadFile,
MSDOSReadFile,
MSDOSGetDirEntry,
MSDOSGetFileBlock,
MSDOSGetUUID,
MSDOSGetDescription,
MSDOSFree,
0, kBIOSDevTypeHardDrive, kBVFlagEFISystem);
}
break;
if (biosdev == gBIOSDev)
gBIOSBootVolume = bvr;
}
}
default:
if (biosdev == gBIOSDev) {
gBIOSBootVolume = bvr;
}
break;
}
}
if (bvr)
{
// Fixup bvr with the fake fdisk partition type.
if (fsType > 0) bvr->part_type = fsType;
if (bvr)
{
// Fixup bvr with the fake fdisk partition type.
if (fsType > 0) {
bvr->part_type = fsType;
}
bvr->next = map->bvr;
map->bvr = bvr;
++map->bvrcnt;
}
bvr->next = map->bvr;
map->bvr = bvr;
++map->bvrcnt;
}
}
}
}
}
scanErr:
free(buffer);
scanErr:
if (buffer) {
free(buffer);
}
if(map)
{
if(countPtr) *countPtr = map->bvrcnt;
return map->bvr;
}
else
{
if(countPtr) *countPtr = 0;
return NULL;
}
if(map) {
if(countPtr) *countPtr = map->bvrcnt;
{
return map->bvr;
}
} else {
if(countPtr) *countPtr = 0;
{
return NULL;
}
}
}
//==============================================================================
static bool getOSVersion(BVRef bvr, char *str)
{
bool valid = false;
config_file_t systemVersion;
char dirSpec[512];
sprintf(dirSpec, "hd(%d,%d)/System/Library/CoreServices/SystemVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no);
if (!loadConfigFile(dirSpec, &systemVersion))
{
if (!loadConfigFile(dirSpec, &systemVersion)) {
valid = true;
}
else
{
} else {
sprintf(dirSpec, "hd(%d,%d)/System/Library/CoreServices/ServerVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no);
if (!loadConfigFile(dirSpec, &systemVersion))
{
bvr->OSisServer = true;
bvr->OSisServer = true;
valid = true;
}
}
}
if (valid)
{
if (valid) {
const char *val;
int len;
if (getValueForKey(kProductVersion, &val, &len, &systemVersion))
{
if (getValueForKey(kProductVersion, &val, &len, &systemVersion)) {
// getValueForKey uses const char for val
// so copy it and trim
*str = '\0';
strncat(str, val, MIN(len, 4));
} else {
valid = false;
}
else
valid = false;
}
if(!valid)
{
if(!valid) {
int fh = -1;
sprintf(dirSpec, "hd(%d,%d)/.PhysicalMediaInstall", BIOS_DEV_UNIT(bvr), bvr->part_no);
fh = open(dirSpec, 0);
if (fh >= 0)
{
if (fh >= 0) {
valid = true;
bvr->OSisInstaller = true;
strcpy(bvr->OSVersion, "10.7"); // 10.7 +
}
else
{
} else {
close(fh);
}
}
return valid;
}
//==========================================================================
//==============================================================================
static void scanFSLevelBVRSettings(BVRef chain)
{
BVRef bvr;
char dirSpec[512], fileSpec[512];
char label[BVSTRLEN];
int ret;
long flags, time;
int fh, fileSize, error;
BVRef bvr;
char dirSpec[512], fileSpec[512];
char label[BVSTRLEN];
int ret;
long flags, time;
int fh, fileSize, error;
for (bvr = chain; bvr; bvr = bvr->next)
{
ret = -1;
error = 0;
for (bvr = chain; bvr; bvr = bvr->next) {
ret = -1;
error = 0;
//
// Check for alternate volume label on boot helper partitions.
//
if (bvr->flags & kBVFlagBooter)
{
sprintf(dirSpec, "hd(%d,%d)/System/Library/CoreServices/", BIOS_DEV_UNIT(bvr), bvr->part_no);
strcpy(fileSpec, ".disk_label.contentDetails");
ret = GetFileInfo(dirSpec, fileSpec, &flags, &time);
if (!ret)
{
fh = open(strcat(dirSpec, fileSpec), 0);
fileSize = file_size(fh);
if (fileSize > 0 && fileSize < BVSTRLEN)
{
if (read(fh, label, fileSize) != fileSize)
error = -1;
}
else
error = -1;
//
// Check for alternate volume label on boot helper partitions.
//
if (bvr->flags & kBVFlagBooter) {
sprintf(dirSpec, "hd(%d,%d)/System/Library/CoreServices/", BIOS_DEV_UNIT(bvr), bvr->part_no);
strcpy(fileSpec, ".disk_label.contentDetails");
ret = GetFileInfo(dirSpec, fileSpec, &flags, &time);
if (!ret) {
fh = open(strcat(dirSpec, fileSpec), 0);
fileSize = file_size(fh);
if (fileSize > 0 && fileSize < BVSTRLEN) {
if (read(fh, label, fileSize) != fileSize) {
error = -1;
}
} else {
error = -1;
}
close(fh);
close(fh);
if (!error)
{
label[fileSize] = '\0';
strcpy(bvr->altlabel, label);
}
}
}
if (!error) {
label[fileSize] = '\0';
strcpy(bvr->altlabel, label);
}
}
}
//
// Check for SystemVersion.plist or ServerVersion.plist
// to determine if a volume hosts an installed system.
//
if (bvr->flags & kBVFlagNativeBoot)
{
if (getOSVersion(bvr,bvr->OSVersion) == true)
{
bvr->flags |= kBVFlagSystemVolume;
}
}
// Check for SystemVersion.plist or ServerVersion.plist to determine if a volume hosts an installed system.
}
if (bvr->flags & kBVFlagNativeBoot) {
if (getOSVersion(bvr,bvr->OSVersion) == true) {
bvr->flags |= kBVFlagSystemVolume;
}
}
}
}
//==============================================================================
void rescanBIOSDevice(int biosdev)
{
struct DiskBVMap *oldMap = diskResetBootVolumes(biosdev);
scanBootVolumes(biosdev, 0);
}
//==============================================================================
struct DiskBVMap* diskResetBootVolumes(int biosdev)
{
struct DiskBVMap * map;
struct DiskBVMap *prevMap = NULL;
for ( map = gDiskBVMap; map; prevMap = map, map = map->next ) {
if ( biosdev == map->biosdev ) {
break;
}
}
if(map != NULL)
{
verbose("Resetting BIOS device %xh\n", biosdev);
// Reset the biosbuf cache
cache_valid = false;
if(map == gDiskBVMap)
gDiskBVMap = map->next;
else if(prevMap != NULL)
prevMap->next = map->next;
else
stop("");
}
// Return the old map, either to be freed, or reinserted later
return map;
struct DiskBVMap * map;
struct DiskBVMap *prevMap = NULL;
for ( map = gDiskBVMap; map; prevMap = map, map = map->next ) {
if ( biosdev == map->biosdev ) {
break;
}
}
if(map != NULL) {
verbose("Resetting BIOS device %xh\n", biosdev);
// Reset the biosbuf cache
cache_valid = false;
if(map == gDiskBVMap) {
gDiskBVMap = map->next;
} else if(prevMap != NULL) {
prevMap->next = map->next;
} else {
stop("");
}
}
// Return the old map, either to be freed, or reinserted later
return map;
}
//==============================================================================
// Frees a DiskBVMap and all of its BootVolume's
void diskFreeMap(struct DiskBVMap *map)
{
if(map != NULL)
{
while(map->bvr != NULL)
{
BVRef bvr = map->bvr;
map->bvr = bvr->next;
(*bvr->bv_free)(bvr);
}
free(map);
}
if(map != NULL)
{
while(map->bvr != NULL)
{
BVRef bvr = map->bvr;
map->bvr = bvr->next;
(*bvr->bv_free)(bvr);
}
free(map);
}
}
BVRef diskScanBootVolumes( int biosdev, int * countPtr )
//==============================================================================
BVRef diskScanBootVolumes(int biosdev, int * countPtr)
{
struct DiskBVMap * map;
BVRef bvr;
int count = 0;
struct DiskBVMap *map;
BVRef bvr;
int count = 0;
// Find an existing mapping for this device.
// Find an existing mapping for this device.
for ( map = gDiskBVMap; map; map = map->next ) {
if ( biosdev == map->biosdev ) {
count = map->bvrcnt;
break;
}
}
for (map = gDiskBVMap; map; map = map->next)
{
if (biosdev == map->biosdev)
{
count = map->bvrcnt;
break;
}
}
if (map == NULL) {
bvr = diskScanGPTBootVolumes(biosdev, &count);
if (bvr == NULL) {
bvr = diskScanFDiskBootVolumes(biosdev, &count);
}
if (bvr == NULL) {
bvr = diskScanAPMBootVolumes(biosdev, &count);
}
if (bvr)
{
scanFSLevelBVRSettings(bvr);
}
} else {
bvr = map->bvr;
}
if (countPtr) *countPtr += count;
return bvr;
if (map == NULL)
{
bvr = diskScanGPTBootVolumes(biosdev, &count);
if (bvr == NULL)
{
bvr = diskScanFDiskBootVolumes(biosdev, &count);
}
if (bvr == NULL)
{
bvr = diskScanAPMBootVolumes(biosdev, &count);
}
if (bvr)
{
scanFSLevelBVRSettings(bvr);
}
}
else
{
bvr = map->bvr;
}
if (countPtr)
{
*countPtr += count;
}
return bvr;
}
//==============================================================================
BVRef getBVChainForBIOSDev(int biosdev)
{
BVRef chain = NULL;
struct DiskBVMap * map = NULL;
BVRef chain = NULL;
struct DiskBVMap * map = NULL;
for (map = gDiskBVMap; map; map = map->next)
{
if (map->biosdev == biosdev)
{
chain = map->bvr;
break;
}
}
return chain;
for (map = gDiskBVMap; map; map = map->next)
{
if (map->biosdev == biosdev)
{
chain = map->bvr;
break;
}
}
return chain;
}
//==============================================================================
BVRef newFilteredBVChain(int minBIOSDev, int maxBIOSDev, unsigned int allowFlags, unsigned int denyFlags, int *count)
{
BVRef chain = NULL;
BVRef bvr = NULL;
BVRef newBVR = NULL;
BVRef prevBVR = NULL;
BVRef chain = NULL;
BVRef bvr = NULL;
BVRef newBVR = NULL;
BVRef prevBVR = NULL;
struct DiskBVMap * map = NULL;
int bvCount = 0;
struct DiskBVMap * map = NULL;
int bvCount = 0;
const char *raw = 0;
char* val = 0;
int len;
const char *raw = 0;
char* val = 0;
int len;
getValueForKey(kHidePartition, &raw, &len, &bootInfo->chameleonConfig);
if(raw)
{
val = XMLDecode(raw);
}
getValueForKey(kHidePartition, &raw, &len, &bootInfo->chameleonConfig);
if(raw)
{
val = XMLDecode(raw);
}
/*
* Traverse gDISKBVmap to get references for
* individual bvr chains of each drive.
*/
for (map = gDiskBVMap; map; map = map->next)
{
for (bvr = map->bvr; bvr; bvr = bvr->next)
{
/*
* Save the last bvr.
*/
if (newBVR) prevBVR = newBVR;
/*
* Traverse gDISKBVmap to get references for
* individual bvr chains of each drive.
*/
for (map = gDiskBVMap; map; map = map->next)
{
for (bvr = map->bvr; bvr; bvr = bvr->next)
{
/*
* Save the last bvr.
*/
if (newBVR)
{
prevBVR = newBVR;
}
/*
* Allocate and copy the matched bvr entry into a new one.
*/
newBVR = (BVRef) malloc(sizeof(*newBVR));
bcopy(bvr, newBVR, sizeof(*newBVR));
/*
* Allocate and copy the matched bvr entry into a new one.
*/
newBVR = (BVRef) malloc(sizeof(*newBVR));
if (!newBVR)
{
continue;
}
bcopy(bvr, newBVR, sizeof(*newBVR));
/*
* Adjust the new bvr's fields.
*/
newBVR->next = NULL;
newBVR->filtered = true;
/*
* Adjust the new bvr's fields.
*/
newBVR->next = NULL;
newBVR->filtered = true;
if ( (!allowFlags || newBVR->flags & allowFlags)
&& (!denyFlags || !(newBVR->flags & denyFlags) )
&& (newBVR->biosdev >= minBIOSDev && newBVR->biosdev <= maxBIOSDev)
)
newBVR->visible = true;
/*
* Looking for "Hide Partition" entries in 'hd(x,y)|uuid|"label" hd(m,n)|uuid|"label"' format,
* to be able to hide foreign partitions from the boot menu.
*
*/
if ( (newBVR->flags & kBVFlagForeignBoot) )
{
char *start, *next = val;
long len = 0;
do
{
start = strbreak(next, &next, &len);
if(len && matchVolumeToString(newBVR, start, len) )
newBVR->visible = false;
}
while ( next && *next );
}
if ( (!allowFlags || newBVR->flags & allowFlags)
&& (!denyFlags || !(newBVR->flags & denyFlags) )
&& (newBVR->biosdev >= minBIOSDev && newBVR->biosdev <= maxBIOSDev)
) {
newBVR->visible = true;
}
/*
* Use the first bvr entry as the starting chain pointer.
*/
if (!chain)
chain = newBVR;
/*
* Looking for "Hide Partition" entries in 'hd(x,y)|uuid|"label" hd(m,n)|uuid|"label"' format,
* to be able to hide foreign partitions from the boot menu.
*
*/
if ( (newBVR->flags & kBVFlagForeignBoot) ) {
char *start, *next = val;
long len = 0;
do
{
start = strbreak(next, &next, &len);
if(len && matchVolumeToString(newBVR, start, len) )
{
newBVR->visible = false;
}
}
while ( next && *next );
}
/*
* Update the previous bvr's link pointer to use the new memory area.
*/
if (prevBVR)
prevBVR->next = newBVR;
if (newBVR->visible)
bvCount++;
}
}
/*
* Use the first bvr entry as the starting chain pointer.
*/
if (!chain) {
chain = newBVR;
}
/*
* Update the previous bvr's link pointer to use the new memory area.
*/
if (prevBVR) {
prevBVR->next = newBVR;
}
if (newBVR->visible) {
bvCount++;
}
}
}
#if DEBUG //Azi: warning - too big for boot-log.. far too big.. i mean HUGE!! :P
for (bvr = chain; bvr; bvr = bvr->next)
{
printf(" bvr: %d, dev: %d, part: %d, flags: %d, vis: %d\n", bvr, bvr->biosdev, bvr->part_no, bvr->flags, bvr->visible);
}
printf("count: %d\n", bvCount);
getchar();
for (bvr = chain; bvr; bvr = bvr->next)
{
printf(" bvr: %d, dev: %d, part: %d, flags: %d, vis: %d\n", bvr, bvr->biosdev, bvr->part_no, bvr->flags, bvr->visible);
}
printf("count: %d\n", bvCount);
getchar();
#endif
*count = bvCount;
free(val);
return chain;
*count = bvCount;
free(val);
return chain;
}
//==============================================================================
int freeFilteredBVChain(const BVRef chain)
{
int ret = 1;
BVRef bvr = chain;
BVRef nextBVR = NULL;
int ret = 1;
BVRef bvr = chain;
BVRef nextBVR = NULL;
while (bvr)
{
nextBVR = bvr->next;
while (bvr)
{
nextBVR = bvr->next;
if (bvr->filtered)
{
free(bvr);
}
else
{
ret = 0;
break;
}
if (bvr->filtered)
{
free(bvr);
}
else
{
ret = 0;
break;
}
bvr = nextBVR;
}
return ret;
bvr = nextBVR;
}
return ret;
}
//==========================================================================
//==============================================================================
static const struct NamedValue fdiskTypes[] =
{
{ 0x00,0 } /* must be last */
};
//==========================================================================
//==============================================================================
bool matchVolumeToString( BVRef bvr, const char* match, long matchLen)
{
char testStr[128];
if ( !bvr || !match || !*match)
{
return 0;
}
if ( bvr->biosdev < 0x80 || bvr->biosdev >= 0x100 )
{
return 0;
// Try to match hd(x,y) first.
sprintf(testStr, "hd(%d,%d)", BIOS_DEV_UNIT(bvr), bvr->part_no);
if ( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) )
return true;
// Try to match volume UUID.
if ( bvr->fs_getuuid && bvr->fs_getuuid(bvr, testStr) == 0)
{
if( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) )
return true;
}
// Try to match volume label (always quoted).
if ( bvr->description )
{
bvr->description(bvr, testStr, sizeof(testStr)-1);
if( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) )
return true;
}
return false;
}
// Try to match hd(x,y) first.
sprintf(testStr, "hd(%d,%d)", BIOS_DEV_UNIT(bvr), bvr->part_no);
if ( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) )
{
return true;
}
// Try to match volume UUID.
if ( bvr->fs_getuuid && bvr->fs_getuuid(bvr, testStr) == 0)
{
if ( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) )
{
return true;
}
}
// Try to match volume label (always quoted).
if ( bvr->description )
{
bvr->description(bvr, testStr, sizeof(testStr)-1);
if ( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) )
{
return true;
}
}
return false;
}
//==============================================================================
/* If Rename Partition has defined an alias, then extract it for description purpose.
* The format for the rename string is the following:
* hd(x,y)|uuid|"label" "alias";hd(m,n)|uuid|"label" "alias"; etc...
bool getVolumeLabelAlias(BVRef bvr, char* str, long strMaxLen)
{
char *aliasList, *entryStart, *entryNext;
char *aliasList, *entryStart, *entryNext;
if ( !str || strMaxLen <= 0)
return false;
aliasList = XMLDecode(getStringForKey(kRenamePartition, &bootInfo->chameleonConfig));
if ( !aliasList )
return false;
for ( entryStart = entryNext = aliasList;
entryNext && *entryNext;
entryStart = entryNext )
{
char *volStart, *volEnd, *aliasStart;
long volLen, aliasLen;
if ( !str || strMaxLen <= 0)
{
return false;
}
aliasList = XMLDecode(getStringForKey(kRenamePartition, &bootInfo->chameleonConfig));
if ( !aliasList )
{
return false;
}
for ( entryStart = entryNext = aliasList; entryNext && *entryNext; entryStart = entryNext )
{
char *volStart, *volEnd, *aliasStart;
long volLen, aliasLen;
// Delimit current entry
entryNext = strchr(entryStart, ';');
if ( entryNext )
{
*entryNext = '\0';
entryNext++;
}
// Delimit current entry
entryNext = strchr(entryStart, ';');
if ( entryNext )
{
*entryNext = '\0';
entryNext++;
}
volStart = strbreak(entryStart, &volEnd, &volLen);
if(!volLen)
continue;
aliasStart = strbreak(volEnd, 0, &aliasLen);
if(!aliasLen)
continue;
if ( matchVolumeToString(bvr, volStart, volLen) )
{
strncat(str, aliasStart, MIN(strMaxLen, aliasLen));
free(aliasList);
return true;
}
}
volStart = strbreak(entryStart, &volEnd, &volLen);
if(!volLen)
{
continue;
}
aliasStart = strbreak(volEnd, 0, &aliasLen);
if(!aliasLen)
{
continue;
}
if ( matchVolumeToString(bvr, volStart, volLen) )
{
strncat(str, aliasStart, MIN(strMaxLen, aliasLen));
free(aliasList);
return true;
}
}
free(aliasList);
return false;
free(aliasList);
return false;
}
//==============================================================================
void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen, bool useDeviceDescription )
{
unsigned char type;
char *p = str;
unsigned char type;
char *p = str;
if(!bvr || !p || strMaxLen <= 0)
return;
type = (unsigned char) bvr->part_type;
if (useDeviceDescription)
{
int len = getDeviceDescription(bvr, str);
if(len >= strMaxLen)
return;
strcpy(str + len, bvr->OSisInstaller ? " (Installer) " : " ");
len += bvr->OSisInstaller ? 13 : 1;
strMaxLen -= len;
p += len;
}
/* See if a partition rename is preferred */
if(getVolumeLabelAlias(bvr, p, strMaxLen)) {
strncpy(bvr->label, p, strMaxLen);
return; // we're done here no need to seek for real name
}
//
// Get the volume label using filesystem specific functions
// or use the alternate volume label if available.
//
if(!bvr || !p || strMaxLen <= 0)
{
return;
}
type = (unsigned char) bvr->part_type;
if (useDeviceDescription)
{
int len = getDeviceDescription(bvr, str);
if(len >= strMaxLen)
{
return;
}
strcpy(str + len, bvr->OSisInstaller ? " (Installer) " : " ");
len += bvr->OSisInstaller ? 13 : 1;
strMaxLen -= len;
p += len;
}
/* See if a partition rename is preferred */
if (getVolumeLabelAlias(bvr, p, strMaxLen))
{
strncpy(bvr->label, p, strMaxLen);
return; // we're done here no need to seek for real name
}
// Get the volume label using filesystem specific functions or use the alternate volume label if available.
if (*bvr->altlabel != '\0')
strncpy(p, bvr->altlabel, strMaxLen);
{
strncpy(p, bvr->altlabel, strMaxLen);
}
else if (bvr->description)
bvr->description(bvr, p, strMaxLen);
{
bvr->description(bvr, p, strMaxLen);
}
if (*p == '\0') {
const char * name = getNameForValue( fdiskTypes, type );
if (name == NULL) {
name = bvr->type_name;
}
if (name == NULL) {
sprintf(p, "TYPE %02x", type);
} else {
strncpy(p, name, strMaxLen);
}
}
// Set the devices label
sprintf(bvr->label, p);
if (*p == '\0')
{
const char * name = getNameForValue( fdiskTypes, type );
if (name == NULL)
{
name = bvr->type_name;
}
if (name == NULL)
{
sprintf(p, "TYPE %02x", type);
}
else
{
strncpy(p, name, strMaxLen);
}
}
// Set the devices label
sprintf(bvr->label, p);
}
//==========================================================================
int readBootSector( int biosdev, unsigned int secno, void * buffer )
//==============================================================================
int readBootSector(int biosdev, unsigned int secno, void * buffer)
{
struct disk_blk0 * bootSector = (struct disk_blk0 *) buffer;
int error;
int error;
struct disk_blk0 * bootSector = (struct disk_blk0 *) buffer;
if ( bootSector == NULL )
{
if ( gBootSector == NULL )
{
gBootSector = (struct disk_blk0 *) malloc(sizeof(*gBootSector));
if ( gBootSector == NULL ) return -1;
}
bootSector = gBootSector;
}
if (bootSector == NULL)
{
if (gBootSector == NULL)
{
gBootSector = (struct disk_blk0 *) malloc(sizeof(*gBootSector));
error = readBytes( biosdev, secno, 0, BPS, bootSector );
if ( error || bootSector->signature != DISK_SIGNATURE )
return -1;
if (gBootSector == NULL)
{
return -1;
}
}
return 0;
bootSector = gBootSector;
}
error = readBytes(biosdev, secno, 0, BPS, bootSector);
if (error || bootSector->signature != DISK_SIGNATURE)
{
return -1;
}
return 0;
}
//==============================================================================
/*
* Format of boot1f32 block.
*/
#define BOOT1F32_MAGIC "BOOT "
#define BOOT1F32_MAGICLEN 11
struct disk_boot1f32_blk {
unsigned char init[3];
unsigned char fsheader[87];
unsigned char magic[BOOT1F32_MAGICLEN];
unsigned char bootcode[409];
unsigned short signature;
struct disk_boot1f32_blk
{
unsigned char init[3];
unsigned char fsheader[87];
unsigned char magic[BOOT1F32_MAGICLEN];
unsigned char bootcode[409];
unsigned short signature;
};
//==============================================================================
int testFAT32EFIBootSector( int biosdev, unsigned int secno, void * buffer )
{
struct disk_boot1f32_blk * bootSector = (struct disk_boot1f32_blk *) buffer;
int error;
struct disk_boot1f32_blk * bootSector = (struct disk_boot1f32_blk *) buffer;
int error;
if ( bootSector == NULL )
{
if ( gBootSector == NULL )
{
gBootSector = (struct disk_blk0 *) malloc(sizeof(*gBootSector));
if ( gBootSector == NULL ) return -1;
}
bootSector = (struct disk_boot1f32_blk *) gBootSector;
}
if ( bootSector == NULL )
{
if ( gBootSector == NULL )
{
gBootSector = (struct disk_blk0 *) malloc(sizeof(*gBootSector));
if ( gBootSector == NULL )
{
return -1;
}
}
bootSector = (struct disk_boot1f32_blk *) gBootSector;
}
error = readBytes( biosdev, secno, 0, BPS, bootSector );
if ( error || bootSector->signature != DISK_SIGNATURE
|| strncmp((const char *)bootSector->magic, BOOT1F32_MAGIC, BOOT1F32_MAGICLEN) )
return -1;
return 0;
error = readBytes( biosdev, secno, 0, BPS, bootSector );
if ( error || bootSector->signature != DISK_SIGNATURE || strncmp((const char *)bootSector->magic, BOOT1F32_MAGIC, BOOT1F32_MAGICLEN) )
{
return -1;
}
return 0;
}
//==========================================================================
//==============================================================================
// Handle seek request from filesystem modules.
void diskSeek( BVRef bvr, long long position )
void diskSeek(BVRef bvr, long long position)
{
bvr->fs_boff = position / BPS;
bvr->fs_byteoff = position % BPS;
bvr->fs_boff = position / BPS;
bvr->fs_byteoff = position % BPS;
}
//==========================================================================
//==============================================================================
// Handle read request from filesystem modules.
int diskRead( BVRef bvr, long addr, long length )
int diskRead(BVRef bvr, long addr, long length)
{
return readBytes( bvr->biosdev,
bvr->fs_boff + bvr->part_boff,
bvr->fs_byteoff,
length,
(void *) addr );
return readBytes(bvr->biosdev, bvr->fs_boff + bvr->part_boff, bvr->fs_byteoff, length, (void *) addr);
}
//==============================================================================
int rawDiskRead( BVRef bvr, unsigned int secno, void *buffer, unsigned int len )
{
int secs;
unsigned char *cbuf = (unsigned char *)buffer;
unsigned int copy_len;
int rc;
int secs;
unsigned char *cbuf = (unsigned char *)buffer;
unsigned int copy_len;
int rc;
if ((len & (BPS-1)) != 0) {
error("raw disk read not sector aligned");
return -1;
}
secno += bvr->part_boff;
if ((len & (BPS-1)) != 0)
{
error("raw disk read not sector aligned");
return -1;
}
secno += bvr->part_boff;
cache_valid = false;
cache_valid = false;
while (len > 0) {
secs = len / BPS;
if (secs > N_CACHE_SECS) secs = N_CACHE_SECS;
copy_len = secs * BPS;
while (len > 0)
{
secs = len / BPS;
if (secs > N_CACHE_SECS)
{
secs = N_CACHE_SECS;
}
copy_len = secs * BPS;
//printf("rdr: ebiosread(%d, %d, %d)\n", bvr->biosdev, secno, secs);
if ((rc = ebiosread(bvr->biosdev, secno, secs)) != 0) {
/* Ignore corrected ECC errors */
if (rc != ECC_CORRECTED_ERR) {
error(" EBIOS read error: %s\n", bios_error(rc), rc);
error(" Block %d Sectors %d\n", secno, secs);
return rc;
}
}
bcopy( trackbuf, cbuf, copy_len );
len -= copy_len;
cbuf += copy_len;
secno += secs;
spinActivityIndicator(secs);
}
//printf("rdr: ebiosread(%d, %d, %d)\n", bvr->biosdev, secno, secs);
if ((rc = ebiosread(bvr->biosdev, secno, secs)) != 0)
{
/* Ignore corrected ECC errors */
if (rc != ECC_CORRECTED_ERR)
{
error(" EBIOS read error: %s\n", bios_error(rc), rc);
error(" Block %d Sectors %d\n", secno, secs);
return rc;
}
}
bcopy( trackbuf, cbuf, copy_len );
len -= copy_len;
cbuf += copy_len;
secno += secs;
spinActivityIndicator(secs);
}
return 0;
return 0;
}
//==============================================================================
int rawDiskWrite( BVRef bvr, unsigned int secno, void *buffer, unsigned int len )
{
int secs;
unsigned int copy_len;
int rc;
if ((len & (BPS-1)) != 0) {
error("raw disk write not sector aligned");
return -1;
}
secno += bvr->part_boff;
if ((len & (BPS-1)) != 0)
{
error("raw disk write not sector aligned");
return -1;
}
secno += bvr->part_boff;
cache_valid = false;
cache_valid = false;
while (len > 0) {
secs = len / BPS;
if (secs > N_CACHE_SECS) secs = N_CACHE_SECS;
copy_len = secs * BPS;
while (len > 0)
{
secs = len / BPS;
if (secs > N_CACHE_SECS)
{
secs = N_CACHE_SECS;
}
copy_len = secs * BPS;
bcopy( cbuf, trackbuf, copy_len );
//printf("rdr: ebioswrite(%d, %d, %d)\n", bvr->biosdev, secno, secs);
if ((rc = ebioswrite(bvr->biosdev, secno, secs)) != 0) {
error(" EBIOS write error: %s\n", bios_error(rc), rc);
error(" Block %d Sectors %d\n", secno, secs);
return rc;
}
len -= copy_len;
cbuf += copy_len;
secno += secs;
spinActivityIndicator(secs);
}
bcopy( cbuf, trackbuf, copy_len );
//printf("rdr: ebioswrite(%d, %d, %d)\n", bvr->biosdev, secno, secs);
if ((rc = ebioswrite(bvr->biosdev, secno, secs)) != 0)
{
error(" EBIOS write error: %s\n", bios_error(rc), rc);
error(" Block %d Sectors %d\n", secno, secs);
return rc;
}
return 0;
len -= copy_len;
cbuf += copy_len;
secno += secs;
spinActivityIndicator(secs);
}
return 0;
}
//==============================================================================
int diskIsCDROM(BVRef bvr)
{
struct driveInfo di;
struct driveInfo di;
if (getDriveInfo(bvr->biosdev, &di) == 0 && di.no_emulation) {
return 1;
}
return 0;
if (getDriveInfo(bvr->biosdev, &di) == 0 && di.no_emulation)
{
return 1;
}
return 0;
}
//==============================================================================
int biosDevIsCDROM(int biosdev)
{
struct driveInfo di;
struct driveInfo di;
if (getDriveInfo(biosdev, &di) == 0 && di.no_emulation)
{
return 1;
}
return 0;
if (getDriveInfo(biosdev, &di) == 0 && di.no_emulation)
{
return 1;
}
return 0;
}
trunk/i386/libsaio/cache.c
3131
3232
3333
34
35
36
34
35
36
3737
3838
3939
......
4848
4949
5050
51
52
51
52
5353
54
55
54
55
5656
5757
5858
59
60
61
59
60
61
6262
6363
6464
6565
66
66
6767
6868
6969
7070
7171
72
73
72
73
74
75
7476
7577
76
77
78
78
79
80
81
7982
80
81
82
83
84
85
8386
8487
85
86
87
88
89
90
8891
8992
9093
9194
9295
93
94
95
96
97
98
99
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
100111
101112
102
113
103114
104115
105
106
116
107117
108
109
118
119
110120
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
121128
122
123
124
129
130
131
132
133
134
135
136
137
138
139
125140
126
141
127142
128
129
143
144
130145
131
132
133
146
147
148
134149
135
136
137
150
151
152
153
138154
139
155
156
157
158
140159
141160
142
143
144
145
146
147
161
162
163
164
165
148166
149
150
151
152
153
154
155
156
167
168
169
157170
158
159
160
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
161188
162
189
163190
164
191
165192
166
167
168
169
170
171
172
193
194
195
196
197
198
199
173200
174
201
175202
// #include <fs.h>
struct CacheEntry {
CICell ih;
long time;
long long offset;
CICell ih;
long time;
long long offset;
};
typedef struct CacheEntry CacheEntry;
static long gCacheTime;
#ifdef __i386__
static CacheEntry *gCacheEntries;
static char *gCacheBuffer;
static CacheEntry *gCacheEntries;
static char *gCacheBuffer;
#else
static CacheEntry gCacheEntries[kCacheMaxEntries];
static char gCacheBuffer[kCacheSize];
static CacheEntry gCacheEntries[kCacheMaxEntries];
static char gCacheBuffer[kCacheSize];
#endif
#if CACHE_STATS
unsigned long gCacheHits;
unsigned long gCacheMisses;
unsigned long gCacheEvicts;
unsigned long gCacheHits;
unsigned long gCacheMisses;
unsigned long gCacheEvicts;
#endif
void CacheReset()
{
gCacheIH = NULL;
gCacheIH = NULL;
}
void CacheInit( CICell ih, long blockSize )
{
#ifdef __i386__
if ((ih == gCacheIH) && (blockSize == gCacheBlockSize))
return;
if ((ih == gCacheIH) && (blockSize == gCacheBlockSize))
{
return;
}
#endif
if ((blockSize < kCacheMinBlockSize) ||
(blockSize > kCacheMaxBlockSize))
return;
if ((blockSize < kCacheMinBlockSize) || (blockSize > kCacheMaxBlockSize))
{
return;
}
gCacheBlockSize = blockSize;
gCacheNumEntries = kCacheSize / gCacheBlockSize;
gCacheTime = 0;
gCacheBlockSize = blockSize;
gCacheNumEntries = kCacheSize / gCacheBlockSize;
gCacheTime = 0;
#if CACHE_STATS
gCacheHits = 0;
gCacheMisses = 0;
gCacheEvicts = 0;
gCacheHits= 0;
gCacheMisses= 0;
gCacheEvicts= 0;
#endif
gCacheIH = ih;
#ifdef __i386__
if (!gCacheBuffer) gCacheBuffer = (char *) malloc(kCacheSize);
if (!gCacheEntries) gCacheEntries = (CacheEntry *) malloc(kCacheMaxEntries * sizeof(CacheEntry));
if ( !gCacheBuffer || !gCacheEntries )
{
gCacheIH = 0; // invalidate cache
return;
}
if (!gCacheBuffer)
{
gCacheBuffer = (char *) malloc(kCacheSize);
}
if (!gCacheEntries)
{
gCacheEntries = (CacheEntry *) malloc(kCacheMaxEntries * sizeof(CacheEntry));
}
if (!gCacheBuffer || !gCacheEntries)
{
gCacheIH = 0; // invalidate cache
return;
}
#endif
bzero(gCacheEntries, kCacheMaxEntries * sizeof(CacheEntry));
bzero(gCacheEntries, kCacheMaxEntries * sizeof(CacheEntry));
}
long CacheRead( CICell ih, char * buffer, long long offset,
long length, long cache )
long CacheRead(CICell ih, char * buffer, long long offset, long length, long cache)
{
long cnt, oldestEntry = 0, oldestTime, loadCache = 0;
CacheEntry *entry;
long cnt, oldestEntry = 0, oldestTime, loadCache = 0;
CacheEntry *entry;
// See if the data can be cached.
if (cache && (gCacheIH == ih) && (length == gCacheBlockSize)) {
// Look for the data in the cache.
for (cnt = 0; cnt < gCacheNumEntries; cnt++) {
entry = &gCacheEntries[cnt];
if ((entry->ih == ih) && (entry->offset == offset)) {
entry->time = ++gCacheTime;
break;
}
}
// See if the data can be cached.
if (cache && (gCacheIH == ih) && (length == gCacheBlockSize))
{
// Look for the data in the cache.
for (cnt = 0; cnt < gCacheNumEntries; cnt++)
{
entry = &gCacheEntries[cnt];
// If the data was found copy it to the caller.
if (cnt != gCacheNumEntries) {
bcopy(gCacheBuffer + cnt * gCacheBlockSize, buffer, gCacheBlockSize);
if ((entry->ih == ih) && (entry->offset == offset))
{
entry->time = ++gCacheTime;
break;
}
}
// If the data was found copy it to the caller.
if (cnt != gCacheNumEntries)
{
bcopy(gCacheBuffer + cnt * gCacheBlockSize, buffer, gCacheBlockSize);
#if CACHE_STATS
gCacheHits++;
gCacheHits++;
#endif
return gCacheBlockSize;
}
return gCacheBlockSize;
}
// Could not find the data in the cache.
loadCache = 1;
}
// Could not find the data in the cache.
loadCache = 1;
}
// Read the data from the disk.
Seek(ih, offset);
Read(ih, (long)buffer, length);
// Read the data from the disk.
Seek(ih, offset);
Read(ih, (long)buffer, length);
#if CACHE_STATS
if (cache) gCacheMisses++;
if (cache)
{
gCacheMisses++;
}
#endif
// Put the data from the disk in the cache if needed.
if (loadCache) {
// Find a free entry.
oldestTime = gCacheTime;
for (cnt = 0; cnt < gCacheNumEntries; cnt++) {
entry = &gCacheEntries[cnt];
// Put the data from the disk in the cache if needed.
if (loadCache)
{
// Find a free entry.
oldestTime = gCacheTime;
// Found a free entry.
if (entry->ih == 0) break;
if (entry->time < oldestTime) {
oldestTime = entry->time;
oldestEntry = cnt;
}
}
for (cnt = 0; cnt < gCacheNumEntries; cnt++)
{
entry = &gCacheEntries[cnt];
// If no free entry was found, use the oldest.
if (cnt == gCacheNumEntries) {
cnt = oldestEntry;
// Found a free entry.
if (entry->ih == 0)
{
break;
}
if (entry->time < oldestTime)
{
oldestTime = entry->time;
oldestEntry = cnt;
}
}
// If no free entry was found, use the oldest.
if (cnt == gCacheNumEntries)
{
cnt = oldestEntry;
#if CACHE_STATS
gCacheEvicts++;
gCacheEvicts++;
#endif
}
}
// Copy the data from disk to the new entry.
entry = &gCacheEntries[cnt];
entry->ih = ih;
entry->time = ++gCacheTime;
entry->offset = offset;
bcopy(buffer, gCacheBuffer + cnt * gCacheBlockSize, gCacheBlockSize);
}
// Copy the data from disk to the new entry.
entry = &gCacheEntries[cnt];
entry->ih = ih;
entry->time = ++gCacheTime;
entry->offset = offset;
bcopy(buffer, gCacheBuffer + cnt * gCacheBlockSize, gCacheBlockSize);
}
return length;
return length;
}
trunk/i386/libsaio/pci.c
8383
8484
8585
86
87
88
8689
90
8791
8892
8993
......
9195
9296
9397
98
9499
95100
96101
......
102107
103108
104109
110
111
105112
106113
107114
......
124131
125132
126133
127
134
128135
129136
130137
......
136143
137144
138145
146
147
148
149
150
139151
140152
141153
......
151163
152164
153165
154
166
155167
156168
157169
......
159171
160172
161173
162
163
164
165
166
167
168
169
170
171
172
173
174
174
175
176
177
178
179
180
181
182
183
184
185
186
187
175188
176189
177190
......
184197
185198
186199
187
188
200
201
189202
190203
191204
continue;
}
new = (pci_dt_t*)malloc(sizeof(pci_dt_t));
if (!new) {
continue;
}
bzero(new, sizeof(pci_dt_t));
new->dev.addr= pci_addr;
new->vendor_id= id & 0xffff;
new->device_id= (id >> 16) & 0xffff;
new->revision_id= pci_config_read8(pci_addr, PCI_CLASS_REVISION);
new->subsys_id.subsys_id= pci_config_read32(pci_addr, PCI_SUBSYSTEM_VENDOR_ID);
new->class_id= pci_config_read16(pci_addr, PCI_CLASS_DEVICE);
//new->subclass_id= pci_config_read16(pci_addr, PCI_SUBCLASS_DEVICE);
new->parent= start;
header_type = pci_config_read8(pci_addr, PCI_HEADER_TYPE);
scan_pci_bus(new, secondary_bus);
}
break;
default:
break;
}
*current = new;
current = &new->next;
{
return;
}
rcba = pci_config_read32(PCIADDR(0, 0x1f, 0), 0xf0) & ~1;
rcba = pci_config_read32(PCIADDR(0, 0x1f, 0), 0xf0) & ~1; //this is LPC host
fd = (uint32_t *)(rcba + 0x3418);
/* set SMBus Disable (SD) to 0 */
*fd &= ~0x8;
void build_pci_dt(void)
{
root_pci_dev = malloc(sizeof(pci_dt_t));
if (!root_pci_dev) {
return;
}
bzero(root_pci_dev, sizeof(pci_dt_t));
enable_pci_devs();
scan_pci_bus(root_pci_dev, 0);
{
pci_dt_t*current;
pci_dt_t*end;
int dev_path_len = 0;
int dev_path_len = 0;
dev_path[0] = 0;
end = root_pci_dev;
int uid = getPciRootUID();
while (end != pci_dt)
{
current = pci_dt;
while (current->parent != end)
current = current->parent;
end = current;
if (current->parent == root_pci_dev) {
dev_path_len +=
snprintf(dev_path + dev_path_len, sizeof(dev_path) - dev_path_len, "PciRoot(0x%x)/Pci(0x%x,0x%x)", uid,
current->dev.bits.dev, current->dev.bits.func);
} else {
dev_path_len +=
snprintf(dev_path + dev_path_len, sizeof(dev_path) - dev_path_len, "/Pci(0x%x,0x%x)",
current->dev.bits.dev, current->dev.bits.func);
}
current = pci_dt;
while (current->parent != end)
current = current->parent;
end = current;
if (current->parent == root_pci_dev) {
dev_path_len +=
snprintf(dev_path + dev_path_len, sizeof(dev_path) - dev_path_len, "PciRoot(0x%x)/Pci(0x%x,0x%x)", uid,
current->dev.bits.dev, current->dev.bits.func);
} else {
dev_path_len +=
snprintf(dev_path + dev_path_len, sizeof(dev_path) - dev_path_len, "/Pci(0x%x,0x%x)",
current->dev.bits.dev, current->dev.bits.func);
}
}
return dev_path;
}
while (current) {
printf("%02x:%02x.%x [%04x%02x] [%04x:%04x] (subsys [%04x:%04x]):: %s\n",
current->dev.bits.bus, current->dev.bits.dev, current->dev.bits.func,
current->class_id, 0 /* FIXME: what should this be? */,
current->vendor_id, current->device_id,
current->class_id, 0 /* FIXME: what should this be? */,
current->vendor_id, current->device_id,
current->subsys_id.subsys.vendor_id, current->subsys_id.subsys.device_id,
get_pci_dev_path(current));
dump_pci_dt(current->children);
trunk/i386/libsaio/biosfn.c
4848
4949
5050
51
52
53
5154
5255
53
54
55
56
57
58
59
60
61
62
63
56
57
58
59
60
61
62
63
64
65
66
67
6468
6569
70
71
72
6673
6774
68
69
70
71
72
73
74
75
75
76
77
78
79
80
81
82
83
7684
7785
7886
7987
80
81
82
83
88
89
90
91
8492
8593
94
95
96
8697
8798
88
89
90
91
92
93
94
99
100
101
102
103
104
105
106
95107
96
97
98
99
100
101
108
109
110
111
112
113
114
102115
103116
104117
......
165178
166179
167180
168
169
181
182
170183
171
172
173
174
175
184
185
186
187
188
176189
177
178
179
180
181
182
183
184
185
186
190
191
192
193
194
195
196
197
198
199
187200
188
189
190
191
192
201
202
203
204
205
193206
194
195
196
197
198
199
200
201
202
207
208
209
210
211
212
213
214
215
203216
204
217
205218
206
207
208
209
210
211
212
219
220
221
222
223
224
225
213226
214
227
215228
216
217
218
219
220
221
222
223
229
230
231
232
233
234
235
224236
225
226
227
228
229
237
238
239
240
241
230242
231
232
243
244
233245
234
246
235247
236
237
238
239
240
241
242
248
249
250
251
252
253
254
243255
244256
245
246
257
258
247259
248260
249
250
261
262
251263
252264
253
254
255
256
257
258
259
260
265
266
267
268
269
270
271
272
273
274
275
276
261277
262278
263
279
264280
265281
282
283
284
285
266286
267287
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
286306
287
288
289
307
308
309
290310
291
311
292312
293
313
314
315
294316
295
296
297
298
299
300
301
302
303
304
305
306
317
318
319
320
321
322
323
324
325
326
327
328
307329
308
309
310
330
331
332
311333
312
334
313335
314
336
315337
316338
339
340
341
342
317343
318344
319
320
321
345
346
347
348
322349
323350
351
352
353
354
324355
325356
326
327
328
329
357
358
359
360
330361
331362
363
364
365
332366
333367
334
368
335369
336
337
370
371
338372
339
340
341
342
343
344
345
346
373
374
375
376
377
378
379
380
347381
348
349
382
383
350384
351
352
353
385
386
387
388
354389
355
356
357
390
391
392
393
358394
359
360
361
362
363
395
396
397
398
399
364400
365401
402
403
404
366405
367406
368
369
370
371
372
373
374
375
376
377
378
407
379408
380
381
382
383
384
385
386
387
388
389
390
391
409
410
411
412
413
414
415
416
417
418
392419
393
394
395
420
421
422
423
424
425
426
427
428
429
430
431
396432
397
398
399
433
434
435
436
400437
401
402
403
404
405
438
439
440
441
442
443
444
445
446
447
448
406449
407450
451
452
408453
409454
410
411
412
413
414
415
416
417
418
419
420
455
456
457
458
459
460
461
462
463
464
465
421466
422
423
424
425
426
427
428
429
430
431
432
433
434
467
468
469
470
471
472
473
474
475
476
477
478
479
435480
436
437
438
481
482
483
439484
440
441
442
485
486
487
443488
444
445
446
447
448
489
490
491
492
493
449494
450495
451496
452497
453
454
455
456
457
458
498
499
500
501
502
503
459504
460505
506
507
508
461509
462510
463
464
465
466
467
468
469
511
512
513
514
515
516
517
470518
471519
472
520
521
522
523
473524
474525
475526
......
488539
489540
490541
491
542
492543
493544
494
495
496
497
498
499
500
501
545
546
547
548
549
550
551
552
502553
554
503555
504556
505
506557
507
508558
509559
510560
511561
562
512563
513564
514
565
515566
516567
517568
......
568619
569620
570621
622
623
571624
572625
626
627
573628
574
575
629
576630
577631
578632
579633
580634
581635
582
636
637
583638
639
584640
585
586
641
642
587643
644
588645
589
646
590647
591648
592
649
593650
594651
595652
......
620677
621678
622679
623
624
625
680
626681
627682
628683
......
684739
685740
686741
742
743
687744
688745
689
690
691
692
693
694
746
747
748
749
750
751
695752
696753
697754
698755
699
700
701
702
703
704
756
757
758
759
760
761
705762
706763
707764
708765
709
710
711
712
766
767
768
769
713770
714771
715772
716773
717
718
719
720
721
722
774
775
776
777
778
779
723780
724781
725782
726783
727
728
729
730
731
732
733
734
735
784
785
786
787
788
789
790
791
792
736793
737794
738795
739796
740
797
741798
742799
743800
744801
745
746
747
748
802
803
804
805
749806
750807
751808
752809
753810
754811
755
812
756813
757
758
759
760
761
762
763
814
815
816
817
818
819
820
764821
765822
766823
767824
768
769
770
771
772
773
774
775
776
777
778
779
780
781
825
826
827
828
829
830
831
832
833
834
835
836
837
782838
783839
784840
......
790846
791847
792848
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
849
850
851
852
853
854
855
856
857
858
859
860
861
808862
809863
810864
811865
812866
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
836889
837890
838891
......
840893
841894
842895
843
844
896
897
845898
846
847
848
849
850
851
852
853
899
900
901
902
903
904
905
854906
855907
856908
857909
858910
859
860
861
862
863
864
865
866
867
868
869
870
871
872
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
873927
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
901955
902956
903957
......
907961
908962
909963
910
911
912
913
914
915
916
917
918
919
920
921
964
965
966
967
968
969
970
971
972
973
974
975
976
922977
923978
924979
......
927982
928983
929984
930
931
932
933
934
935
936
937
938
939
940
941
942
985
986
987
988
989
990
991
992
993
994
995
996
997
998
943999
9441000
9451001
......
9481004
9491005
9501006
1007
1008
1009
9511010
9521011
9531012
static biosBuf_t bb;
//==============================================================================
int bgetc(void)
{
/* Poll for the next character. Most real BIOS do not need this as the
INT 16h,AH=0h function will block until one is received.
Unfortunately, Apple's EFI CSM will never wake up. This idea is lifted
from the grub-a20.patch to GRUB's stage2/asm.S file.
*/
while(!readKeyboardStatus())
;
bb.intno = 0x16;
bb.eax.r.h = 0x00;
bios(&bb);
return bb.eax.rr;
/* Poll for the next character. Most real BIOS do not need this as the
INT 16h,AH=0h function will block until one is received.
Unfortunately, Apple's EFI CSM will never wake up. This idea is lifted
from the grub-a20.patch to GRUB's stage2/asm.S file.
*/
while(!readKeyboardStatus());
bb.intno = 0x16;
bb.eax.r.h = 0x00;
bios(&bb);
return bb.eax.rr;
}
//==============================================================================
int readKeyboardStatus(void)
{
bb.intno = 0x16;
bb.eax.r.h = 0x01;
bios(&bb);
if (bb.flags.zf) {
return 0;
} else {
return bb.eax.rr;
}
bb.intno = 0x16;
bb.eax.r.h = 0x01;
bios(&bb);
if (bb.flags.zf) {
return 0;
} else {
return bb.eax.rr;
}
}
int readKeyboardShiftFlags(void)
{
bb.intno = 0x16;
bb.eax.r.h = 0x02;
bios(&bb);
return bb.eax.r.l;
bb.intno = 0x16;
bb.eax.r.h = 0x02;
bios(&bb);
return bb.eax.r.l;
}
//==============================================================================
unsigned int time18(void)
{
union {
struct {
unsigned int low:16;
unsigned int high:16;
} s;
unsigned int i;
} time;
union {
struct {
unsigned int low:16;
unsigned int high:16;
} s;
unsigned int i;
} time;
bb.intno = 0x1a;
bb.eax.r.h = 0x00;
bios(&bb);
time.s.low = bb.edx.rr;
time.s.high = bb.ecx.rr;
return time.i;
bb.intno = 0x1a;
bb.eax.r.h = 0x00;
bios(&bb);
time.s.low = bb.edx.rr;
time.s.high = bb.ecx.rr;
return time.i;
}
#if 0
unsigned long * conMemSizePtr,
unsigned long * extMemSizePtr )
{
#define kMemoryMapSignature 'SMAP'
#define kDescriptorSizeMin 20
#define kMemoryMapSignature 'SMAP'
#define kDescriptorSizeMin 20
MemoryRange *range = (MemoryRange *)BIOS_ADDR;
unsigned longcount = 0;
// unsigned longrerangedCount;
unsigned long longconMemSize = 0;
unsigned long longextMemSize = 0;
MemoryRange *range = (MemoryRange *)BIOS_ADDR;
unsigned longcount = 0;
// unsigned longrerangedCount;
unsigned long longconMemSize = 0;
unsigned long longextMemSize = 0;
// Prepare for the INT15 E820h call. Each call returns a single
// memory range. A continuation value is returned that must be
// provided on a subsequent call to fetch the next range.
//
// Certain BIOSes (Award 6.00PG) expect the upper word in EAX
// to be cleared on entry, otherwise only a single range will
// be reported.
//
// Some BIOSes will simply ignore the value of ECX on entry.
// Probably best to keep its value at 20 to avoid surprises.
// Prepare for the INT15 E820h call. Each call returns a single
// memory range. A continuation value is returned that must be
// provided on a subsequent call to fetch the next range.
//
// Certain BIOSes (Award 6.00PG) expect the upper word in EAX
// to be cleared on entry, otherwise only a single range will
// be reported.
//
// Some BIOSes will simply ignore the value of ECX on entry.
// Probably best to keep its value at 20 to avoid surprises.
//printf("Get memory map 0x%x, %d\n", rangeArray); getchar();
if (maxRangeCount > (BIOS_LEN / sizeof(MemoryRange))) {
maxRangeCount = (BIOS_LEN / sizeof(MemoryRange));
}
bb.ebx.rx = 0; // Initial continuation value must be zero.
//printf("Get memory map 0x%x, %d\n", rangeArray); getchar();
if (maxRangeCount > (BIOS_LEN / sizeof(MemoryRange))) {
maxRangeCount = (BIOS_LEN / sizeof(MemoryRange));
}
bb.ebx.rx = 0; // Initial continuation value must be zero.
while ( count < maxRangeCount )
{
bb.intno = 0x15;
bb.eax.rx = 0xe820;
bb.ecx.rx = kDescriptorSizeMin;
bb.edx.rx = kMemoryMapSignature;
bb.edi.rr = NORMALIZED_OFFSET( (unsigned long) range );
bb.es = NORMALIZED_SEGMENT( (unsigned long) range );
bios(&bb);
while (count < maxRangeCount)
{
bb.intno = 0x15;
bb.eax.rx = 0xe820;
bb.ecx.rx = kDescriptorSizeMin;
bb.edx.rx = kMemoryMapSignature;
bb.edi.rr = NORMALIZED_OFFSET( (unsigned long) range );
bb.es = NORMALIZED_SEGMENT( (unsigned long) range );
bios(&bb);
// Check for errors.
// Check for errors.
if ( bb.flags.cf
|| bb.eax.rx != kMemoryMapSignature
|| bb.ecx.rx != kDescriptorSizeMin ) {
//printf("Got an error %x %x %x\n", bb.flags.cf,
// bb.eax.rx, bb.ecx.rx);
break;
}
if ( bb.flags.cf
|| bb.eax.rx != kMemoryMapSignature
|| bb.ecx.rx != kDescriptorSizeMin ) {
//printf("Got an error %x %x %x\n", bb.flags.cf,
// bb.eax.rx, bb.ecx.rx);
break;
}
// Tally up the conventional/extended memory sizes.
// Tally up the conventional/extended memory sizes.
if ( range->type == kMemoryRangeUsable ||
range->type == kMemoryRangeACPI ||
range->type == kMemoryRangeNVS )
{
// Tally the conventional memory ranges.
if ( range->base + range->length <= 0xa0000 ) {
conMemSize += range->length;
}
if ( range->type == kMemoryRangeUsable ||
range->type == kMemoryRangeACPI ||
range->type == kMemoryRangeNVS ) {
// Tally the conventional memory ranges.
if ( range->base + range->length <= 0xa0000 ) {
conMemSize += range->length;
}
// Record the top of extended memory.
if ( range->base >= EXTENDED_ADDR ) {
extMemSize += range->length;
}
}
// Record the top of extended memory.
if (range->base >= EXTENDED_ADDR) {
extMemSize += range->length;
}
}
range++;
count++;
range++;
count++;
// Is this the last address range?
// Is this the last address range?
if ( bb.ebx.rx == 0 ) {
//printf("last range\n");
break;
}
}
*conMemSizePtr = conMemSize / 1024; // size in KB
*extMemSizePtr = extMemSize / 1024; // size in KB
if ( bb.ebx.rx == 0 ) {
//printf("last range\n");
break;
}
}
*conMemSizePtr = conMemSize / 1024; // size in KB
*extMemSizePtr = extMemSize / 1024; // size in KB
#if 0
rerangedCount = rerangeMemoryMap(count);
range += rerangedCount - count;
rerangedCount = rerangeMemoryMap(count);
range += rerangedCount - count;
#endif
// Copy out data
bcopy((char *)BIOS_ADDR, rangeArray, ((char *)range - (char *)BIOS_ADDR));
// Copy out data
bcopy((char *)BIOS_ADDR, rangeArray, ((char *)range - (char *)BIOS_ADDR));
#if DEBUG
{
int i;
printf("%d total ranges\n", count); getchar();
for (i=0, range = rangeArray; i<count; i++, range++) {
printf("range: type %d, base 0x%x, length 0x%x\n",
range->type, (unsigned int)range->base, (unsigned int)range->length); getchar();
}
}
{
int i;
printf("%d total ranges\n", count);
getchar();
for (i = 0, range = rangeArray; i<count; i++, range++) {
printf("range: type %d, base 0x%x, length 0x%x\n",
range->type, (unsigned int)range->base, (unsigned int)range->length);
getchar();
}
}
#endif
return count;
return count;
}
//==============================================================================
unsigned long getExtendedMemorySize()
{
// Get extended memory size for large configurations. Not used unless
// the INT15, E820H call (Get System Address Map) failed.
//
// Input:
//
// AX Function Code E801h
//
// Outputs:
//
// CF Carry Flag Carry cleared indicates no error.
// AX Extended 1 Number of contiguous KB between 1 and 16 MB,
// maximum 0x3C00 = 15 MB.
// BX Extended 2 Number of contiguous 64 KB blocks between
// 16 MB and 4 GB.
// CX Configured 1 Number of contiguous KB between 1 and 16 MB,
// maximum 0x3C00 = 15 MB.
// DX Configured 2 Number of contiguous 64 KB blocks between
// 16 MB and 4 GB.
// Get extended memory size for large configurations. Not used unless
// the INT15, E820H call (Get System Address Map) failed.
//
// Input:
//
// AX Function Code E801h
//
// Outputs:
//
// CF Carry Flag Carry cleared indicates no error.
// AX Extended 1 Number of contiguous KB between 1 and 16 MB,
// maximum 0x3C00 = 15 MB.
// BX Extended 2 Number of contiguous 64 KB blocks between
// 16 MB and 4 GB.
// CX Configured 1 Number of contiguous KB between 1 and 16 MB,
// maximum 0x3C00 = 15 MB.
// DX Configured 2 Number of contiguous 64 KB blocks between
// 16 MB and 4 GB.
bb.intno = 0x15;
bb.eax.rx = 0xe801;
bios(&bb);
bb.intno = 0x15;
bb.eax.rx = 0xe801;
bios(&bb);
// Return the size of memory above 1MB (extended memory) in kilobytes.
// Return the size of memory above 1MB (extended memory) in kilobytes.
if ( bb.flags.cf == 0 ) return (bb.ebx.rr * 64 + bb.eax.rr);
if (bb.flags.cf == 0) {
return (bb.ebx.rr * 64 + bb.eax.rr);
}
// Get Extended memory size. Called on last resort since the return
// value is limited to 16-bits (a little less than 64MB max). May
// not be supported by modern BIOSes.
//
// Input:
//
// AX Function Code E801h
//
// Outputs:
//
// CF Carry Flag Carry cleared indicates no error.
// AX Memory Count Number of contiguous KB above 1MB.
// Get Extended memory size. Called on last resort since the return
// value is limited to 16-bits (a little less than 64MB max). May
// not be supported by modern BIOSes.
//
// Input:
//
// AX Function Code E801h
//
// Outputs:
//
// CF Carry Flag Carry cleared indicates no error.
// AX Memory Count Number of contiguous KB above 1MB.
bb.intno = 0x15;
bb.eax.rx = 0x88;
bios(&bb);
bb.intno = 0x15;
bb.eax.rx = 0x88;
bios(&bb);
// Return the size of memory above 1MB (extended memory) in kilobytes.
// Return the size of memory above 1MB (extended memory) in kilobytes.
return bb.flags.cf ? 0 : bb.eax.rr;
return bb.flags.cf ? 0 : bb.eax.rr;
}
//==============================================================================
unsigned long getConventionalMemorySize()
{
bb.intno = 0x12;
bios(&bb);
return bb.eax.rr; // kilobytes
bb.intno = 0x12;
bios(&bb);
return bb.eax.rr; // kilobytes
}
//==============================================================================
void video_mode(int mode)
{
bb.intno = 0x10;
bb.eax.r.h = 0x00;
bb.eax.r.l = mode;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = 0x00;
bb.eax.r.l = mode;
bios(&bb);
}
//==============================================================================
int biosread(int dev, int cyl, int head, int sec, int num)
{
int i;
int i;
bb.intno = 0x13;
sec += 1; /* sector numbers start at 1 */
bb.intno = 0x13;
sec += 1; // sector numbers start at 1.
for (i=0;;) {
bb.ecx.r.h = cyl;
bb.ecx.r.l = ((cyl & 0x300) >> 2) | (sec & 0x3F);
bb.edx.r.h = head;
bb.edx.r.l = dev;
bb.eax.r.l = num;
bb.ebx.rr = OFFSET(ptov(BIOS_ADDR));
bb.es = SEGMENT(ptov(BIOS_ADDR));
for (i = 0; ;) {
bb.ecx.r.h = cyl;
bb.ecx.r.l = ((cyl & 0x300) >> 2) | (sec & 0x3F);
bb.edx.r.h = head;
bb.edx.r.l = dev;
bb.eax.r.l = num;
bb.ebx.rr = OFFSET(ptov(BIOS_ADDR));
bb.es = SEGMENT(ptov(BIOS_ADDR));
bb.eax.r.h = 0x02;
bios(&bb);
bb.eax.r.h = 0x02;
bios(&bb);
/* In case of a successful call, make sure we set AH (return code) to zero. */
if (bb.flags.cf == 0)
bb.eax.r.h = 0;
// In case of a successful call, make sure we set AH (return code) to zero.
if (bb.flags.cf == 0) {
bb.eax.r.h = 0;
}
/* Now we can really check for the return code (AH) value. */
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
break;
// Now we can really check for the return code (AH) value.
if ((bb.eax.r.h == 0x00) || (i++ >= 5)) {
break;
}
/* reset disk subsystem and try again */
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
// Reset disk subsystem and try again.
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
}
//==============================================================================
int ebiosread(int dev, unsigned long long sec, int count)
{
int i;
static struct {
unsigned char size;
unsigned char reserved;
unsigned char numblocks;
unsigned char reserved2;
unsigned short bufferOffset;
unsigned short bufferSegment;
unsigned long long startblock;
} addrpacket __attribute__((aligned(16))) = {0};
addrpacket.size = sizeof(addrpacket);
int i;
for (i=0;;) {
bb.intno = 0x13;
bb.eax.r.h = 0x42;
bb.edx.r.l = dev;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);
bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);
addrpacket.reserved = addrpacket.reserved2 = 0;
addrpacket.numblocks = count;
addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
addrpacket.startblock = sec;
bios(&bb);
static struct {
unsigned char size;
unsigned char reserved;
unsigned char numblocks;
unsigned char reserved2;
unsigned short bufferOffset;
unsigned short bufferSegment;
unsigned long long startblock;
} addrpacket __attribute__((aligned(16))) = {0};
addrpacket.size = sizeof(addrpacket);
/* In case of a successful call, make sure we set AH (return code) to zero. */
if (bb.flags.cf == 0)
bb.eax.r.h = 0;
for (i = 0; ;) {
bb.intno = 0x13;
bb.eax.r.h = 0x42;
bb.edx.r.l = dev;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);
bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);
addrpacket.reserved = addrpacket.reserved2 = 0;
addrpacket.numblocks = count;
addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
addrpacket.startblock = sec;
bios(&bb);
/* Now we can really check for the return code (AH) value. */
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
break;
// In case of a successful call, make sure we set AH (return code) to zero.
if (bb.flags.cf == 0) {
bb.eax.r.h = 0;
}
/* reset disk subsystem and try again */
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
// Now we can really check for the return code (AH) value.
if ((bb.eax.r.h == 0x00) || (i++ >= 5)) {
break;
}
// Reset disk subsystem and try again.
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
}
//==============================================================================
int ebioswrite(int dev, long sec, int count)
{
int i;
static struct {
unsigned char size;
unsigned char reserved;
unsigned char numblocks;
unsigned char reserved2;
unsigned short bufferOffset;
unsigned short bufferSegment;
unsigned long long startblock;
} addrpacket __attribute__((aligned(16))) = {0};
addrpacket.size = sizeof(addrpacket);
int i;
static struct {
unsigned char size;
unsigned char reserved;
unsigned char numblocks;
unsigned char reserved2;
unsigned short bufferOffset;
unsigned short bufferSegment;
unsigned long long startblock;
} addrpacket __attribute__((aligned(16))) = {0};
addrpacket.size = sizeof(addrpacket);
for (i=0;;) {
bb.intno = 0x13;
bb.eax.r.l = 0; /* Don't verify */
bb.eax.r.h = 0x43;
bb.edx.r.l = dev;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);
bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);
addrpacket.reserved = addrpacket.reserved2 = 0;
addrpacket.numblocks = count;
addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
addrpacket.startblock = sec;
bios(&bb);
for (i=0;;) {
bb.intno = 0x13;
bb.eax.r.l = 0; /* Don't verify */
bb.eax.r.h = 0x43;
bb.edx.r.l = dev;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);
bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);
addrpacket.reserved = addrpacket.reserved2 = 0;
addrpacket.numblocks = count;
addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
addrpacket.startblock = sec;
bios(&bb);
/* In case of a successful call, make sure we set AH (return code) to zero. */
if (bb.flags.cf == 0)
bb.eax.r.h = 0;
/* In case of a successful call, make sure we set AH (return code) to zero. */
if (bb.flags.cf == 0)
bb.eax.r.h = 0;
/* Now we can really check for the return code (AH) value. */
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
break;
/* Now we can really check for the return code (AH) value. */
if ((bb.eax.r.h == 0x00) || (i++ >= 5))
break;
/* reset disk subsystem and try again */
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
/* reset disk subsystem and try again */
bb.eax.r.h = 0x00;
bios(&bb);
}
return bb.eax.r.h;
}
void bios_putchar(int ch)
{
bb.intno = 0x10;
bb.ebx.r.h = 0x00; /* background black */
bb.ebx.r.l = 0x0F; /* foreground white */
bb.eax.r.h = 0x0e;
bb.eax.r.l = ch;
bios(&bb);
bb.intno = 0x10;
bb.ebx.r.h = 0x00; /* background black */
bb.ebx.r.l = 0x0F; /* foreground white */
bb.eax.r.h = 0x0e;
bb.eax.r.l = ch;
bios(&bb);
}
//==============================================================================
void putca(int ch, int attr, int repeat)
{
bb.intno = 0x10;
bb.ebx.r.h = 0x00; /* page number */
bb.ebx.r.l = attr; /* attribute */
bb.eax.r.h = 0x9;
bb.eax.r.l = ch;
bb.ecx.rx = repeat; /* repeat count */
bios(&bb);
bb.intno = 0x10;
bb.ebx.r.h = 0x00; /* page number */
bb.ebx.r.l = attr; /* attribute */
bb.eax.r.h = 0x9;
bb.eax.r.l = ch;
bb.ecx.rx = repeat; /* repeat count */
bios(&bb);
}
/* Check to see if the passed-in drive is in El Torito no-emulation mode. */
//==============================================================================
// Check to see if the passed-in drive is in El Torito no-emulation mode.
int is_no_emulation(int drive)
{
struct packet {
unsigned char reseved;
} __attribute__((packed));
static struct packet pkt;
bzero(&pkt, sizeof(pkt));
pkt.packet_size = 0x13;
bb.intno= 0x13;
bb.eax.r.h= 0x4b;
bb.eax.r.l= 0x01; // subfunc: get info
bb.edx.r.l= drive;
bb.esi.rr= NORMALIZED_OFFSET((unsigned)&pkt);
bb.ds= NORMALIZED_SEGMENT((unsigned)&pkt);
bb.intno = 0x13;
bb.eax.r.h = 0x4b;
bb.eax.r.l = 0x01; // subfunc: get info
bb.edx.r.l = drive;
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&pkt);
bb.ds = NORMALIZED_SEGMENT((unsigned)&pkt);
bios(&bb);
#if DEBUG
printf("el_torito info drive %x\n", drive);
printf("--> cf %x, eax %x\n", bb.flags.cf, bb.eax.rr);
printf("pkt_size: %x\n", pkt.packet_size);
printf("media_type: %x\n", pkt.media_type);
printf("drive_num: %x\n", pkt.drive_num);
printf("device_spec: %x\n", pkt.device_spec);
pause();
#endif
/* Some BIOSes erroneously return cf = 1 */
/* Just check to see if the drive number is the same. */
if (pkt.drive_num == drive) {
#endif
//==============================================================================
int get_drive_info(int drive, struct driveInfo *dp)
{
int ret = 0;
boot_drive_info_t *di = &dp->di;
int ret = 0;
#if UNUSED
if (maxhd == 0) {
bb.intno = 0x13;
bb.eax.r.h = 0x08;
bb.edx.r.l = 0x80;
bios(&bb);
if (bb.flags.cf == 0)
if (bb.flags.cf == 0) {
maxhd = 0x7f + bb.edx.r.l;
}
};
if (drive > maxhd)
if (drive > maxhd) {
return 0;
}
#endif
bzero(dp, sizeof(struct driveInfo));
dp->biosdev = drive;
/* Check for El Torito no-emulation mode. */
dp->no_emulation = is_no_emulation(drive);
if (bb.flags.cf != 0 /* || params.phys_sectors < 2097152 */) {
dp->uses_ebios = 0;
di->params.buf_size = 1;
}
else
{
} else {
bcopy(&params, &di->params, sizeof(params));
if (drive >= BASE_HD_DRIVE &&
return ret;
}
//==============================================================================
int ebiosEjectMedia(int biosdev)
{
bb.intno = 0x13;
bb.eax.r.h = 0x46;
bb.eax.r.l = 0;
bb.edx.rx = biosdev;
bios(&bb);
return bb.eax.r.h;
bb.intno = 0x13;
bb.eax.r.h = 0x46;
bb.eax.r.l = 0;
bb.edx.rx = biosdev;
bios(&bb);
return bb.eax.r.h;
}
void setCursorPosition(int x, int y, int page)
{
bb.intno = 0x10;
bb.eax.r.h = 0x02;
bb.ebx.r.h = page; /* page 0 for graphics */
bb.edx.r.l = x;
bb.edx.r.h = y;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = 0x02;
bb.ebx.r.h = page; /* page 0 for graphics */
bb.edx.r.l = x;
bb.edx.r.h = y;
bios(&bb);
}
void setCursorType(int type)
{
bb.intno = 0x10;
bb.eax.r.h = 0x01;
bb.ecx.rr = type;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = 0x01;
bb.ecx.rr = type;
bios(&bb);
}
void getCursorPositionAndType(int * x, int * y, int * type)
{
bb.intno = 0x10;
bb.eax.r.h = 0x03;
bios(&bb);
*x = bb.edx.r.l;
*y = bb.edx.r.h;
*type = bb.ecx.rr;
bb.intno = 0x10;
bb.eax.r.h = 0x03;
bios(&bb);
*x = bb.edx.r.l;
*y = bb.edx.r.h;
*type = bb.ecx.rr;
}
void scollPage(int x1, int y1, int x2, int y2, int attr, int rows, int dir)
{
bb.intno = 0x10;
bb.eax.r.h = (dir > 0) ? 0x06 : 0x07;
bb.eax.r.l = rows;
bb.ebx.r.h = attr;
bb.ecx.r.h = y1;
bb.ecx.r.l = x1;
bb.edx.r.h = y2;
bb.edx.r.l = x2;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = (dir > 0) ? 0x06 : 0x07;
bb.eax.r.l = rows;
bb.ebx.r.h = attr;
bb.ecx.r.h = y1;
bb.ecx.r.l = x1;
bb.edx.r.h = y2;
bb.edx.r.l = x2;
bios(&bb);
}
void clearScreenRows( int y1, int y2 )
{
scollPage( 0, y1, 80 - 1, y2, 0x07, y2 - y1 + 1, 1 );
scollPage( 0, y1, 80 - 1, y2, 0x07, y2 - y1 + 1, 1 );
}
void setActiveDisplayPage( int page )
{
bb.intno = 0x10;
bb.eax.r.h = 5;
bb.eax.r.l = page;
bios(&bb);
bb.intno = 0x10;
bb.eax.r.h = 5;
bb.eax.r.l = page;
bios(&bb);
}
#if DEBUG
int terminateDiskEmulation()
{
static char cd_spec[0x13];
static char cd_spec[0x13];
bb.intno = 0x13;
bb.eax.r.h = 0x4b;
bb.eax.r.l = 0; // subfunc: terminate emulation
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&cd_spec);
bb.ds = NORMALIZED_SEGMENT((unsigned)&cd_spec);
bios(&bb);
return bb.eax.r.h;
bb.intno = 0x13;
bb.eax.r.h = 0x4b;
bb.eax.r.l = 0; // subfunc: terminate emulation
bb.esi.rr = NORMALIZED_OFFSET((unsigned)&cd_spec);
bb.ds = NORMALIZED_SEGMENT((unsigned)&cd_spec);
bios(&bb);
return bb.eax.r.h;
}
int readDriveParameters(int drive, struct driveParameters *dp)
{
bb.intno = 0x13;
bb.edx.r.l = drive;
bb.eax.r.h = 0x08;
bios(&bb);
if (bb.eax.r.h == 0) {
dp->heads = bb.edx.r.h;
dp->sectors = bb.ecx.r.l & 0x3F;
dp->cylinders = bb.ecx.r.h | ((bb.ecx.r.l & 0xC0) << 2);
dp->totalDrives = bb.edx.r.l;
} else {
bzero(dp, sizeof(*dp));
}
return bb.eax.r.h;
bb.intno = 0x13;
bb.edx.r.l = drive;
bb.eax.r.h = 0x08;
bios(&bb);
if (bb.eax.r.h == 0) {
dp->heads = bb.edx.r.h;
dp->sectors = bb.ecx.r.l & 0x3F;
dp->cylinders = bb.ecx.r.h | ((bb.ecx.r.l & 0xC0) << 2);
dp->totalDrives = bb.edx.r.l;
} else {
bzero(dp, sizeof(*dp));
}
return bb.eax.r.h;
}
#endif
int
APMPresent(void)
{
bb.intno = APM_INTNO;
bb.eax.r.h = APM_INTCODE;
bb.eax.r.l = 0x00;
bb.ebx.rr = 0x0000;
bios(&bb);
if ((bb.flags.cf == 0) &&
(bb.ebx.r.h == 'P') &&
(bb.ebx.r.l == 'M')) {
/* Success */
bootArgs->apmConfig.major_vers = bb.eax.r.h;
bootArgs->apmConfig.minor_vers = bb.eax.r.l;
bootArgs->apmConfig.flags.data = bb.ecx.rr;
return 1;
}
return 0;
bb.intno = APM_INTNO;
bb.eax.r.h = APM_INTCODE;
bb.eax.r.l = 0x00;
bb.ebx.rr = 0x0000;
bios(&bb);
if ((bb.flags.cf == 0) && (bb.ebx.r.h == 'P') && (bb.ebx.r.l == 'M')) {
/* Success */
bootArgs->apmConfig.major_vers = bb.eax.r.h;
bootArgs->apmConfig.minor_vers = bb.eax.r.l;
bootArgs->apmConfig.flags.data = bb.ecx.rr;
return 1;
}
return 0;
}
int
APMConnect32(void)
{
bb.intno = APM_INTNO;
bb.eax.r.h = APM_INTCODE;
bb.eax.r.l = 0x03;
bb.ebx.rr = 0x0000;
bios(&bb);
if (bb.flags.cf == 0) {
/* Success */
bootArgs->apmConfig.cs32_base = (bb.eax.rr) << 4;
bootArgs->apmConfig.entry_offset = bb.ebx.rx;
bootArgs->apmConfig.cs16_base = (bb.ecx.rr) << 4;
bootArgs->apmConfig.ds_base = (bb.edx.rr) << 4;
if (bootArgs->apmConfig.major_vers >= 1 &&
bootArgs->apmConfig.minor_vers >= 1) {
bootArgs->apmConfig.cs_length = bb.esi.rr;
bootArgs->apmConfig.ds_length = bb.edi.rr;
} else {
bootArgs->apmConfig.cs_length =
bootArgs->apmConfig.ds_length = 64 * 1024;
}
bootArgs->apmConfig.connected = 1;
return 1;
}
return 0;
bb.intno = APM_INTNO;
bb.eax.r.h = APM_INTCODE;
bb.eax.r.l = 0x03;
bb.ebx.rr = 0x0000;
bios(&bb);
if (bb.flags.cf == 0) {
/* Success */
bootArgs->apmConfig.cs32_base = (bb.eax.rr) << 4;
bootArgs->apmConfig.entry_offset = bb.ebx.rx;
bootArgs->apmConfig.cs16_base = (bb.ecx.rr) << 4;
bootArgs->apmConfig.ds_base = (bb.edx.rr) << 4;
if (bootArgs->apmConfig.major_vers >= 1 && bootArgs->apmConfig.minor_vers >= 1) {
bootArgs->apmConfig.cs_length = bb.esi.rr;
bootArgs->apmConfig.ds_length = bb.edi.rr;
} else {
bootArgs->apmConfig.cs_length =
bootArgs->apmConfig.ds_length = 64 * 1024;
}
bootArgs->apmConfig.connected = 1;
return 1;
}
return 0;
}
#endif /* APM_SUPPORT */
#ifdef EISA_SUPPORT
bool eisa_present(void)
{
static bool checked = false;
static bool isEISA;
static bool checked = false;
static bool isEISA;
if (!checked) {
if (strncmp((char *)0xfffd9, "EISA", 4) == 0)
isEISA = true;
checked = true;
}
return (isEISA);
if (!checked) {
if (strncmp((char *)0xfffd9, "EISA", 4) == 0) {
isEISA = true;
}
checked = true;
}
return (isEISA);
}
int
ReadEISASlotInfo(EISA_slot_info_t *ep, int slot)
{
union {
struct {
unsigned char char2h :2;
unsigned char char1 :5;
unsigned char char3 :5;
unsigned char char2l :3;
unsigned char d2 :4;
unsigned char d1 :4;
unsigned char d4 :4;
unsigned char d3 :4;
} s;
unsigned char data[4];
} u;
static char hex[0x10] = "0123456789ABCDEF";
union
{
struct
{
unsigned char char2h :2;
unsigned char char1 :5;
unsigned char char3 :5;
unsigned char char2l :3;
unsigned char d2 :4;
unsigned char d1 :4;
unsigned char d4 :4;
unsigned char d3 :4;
} s;
unsigned char data[4];
} u;
static char hex[0x10] = "0123456789ABCDEF";
bb.intno = 0x15;
bb.eax.r.h = 0xd8;
bb.eax.r.l = 0x00;
bb.ecx.r.l = slot;
bios(&bb);
if (bb.flags.cf)
return bb.eax.r.h;
ep->u_ID.d = bb.eax.r.l;
ep->configMajor = bb.ebx.r.h;
ep->configMinor = bb.ebx.r.l;
ep->checksum = bb.ecx.rr;
ep->numFunctions = bb.edx.r.h;
ep->u_resources.d = bb.edx.r.l;
u.data[0] = bb.edi.r.l;
u.data[1] = bb.edi.r.h;
u.data[2] = bb.esi.r.l;
u.data[3] = bb.esi.r.h;
ep->id[0] = u.s.char1 + ('A' - 1);
ep->id[1] = (u.s.char2l | (u.s.char2h << 3)) + ('A' - 1);
ep->id[2] = u.s.char3 + ('A' - 1);
ep->id[3] = hex[u.s.d1];
ep->id[4] = hex[u.s.d2];
ep->id[5] = hex[u.s.d3];
ep->id[6] = hex[u.s.d4];
ep->id[7] = 0;
return 0;
bb.intno = 0x15;
bb.eax.r.h = 0xd8;
bb.eax.r.l = 0x00;
bb.ecx.r.l = slot;
bios(&bb);
if (bb.flags.cf)
return bb.eax.r.h;
ep->u_ID.d = bb.eax.r.l;
ep->configMajor = bb.ebx.r.h;
ep->configMinor = bb.ebx.r.l;
ep->checksum = bb.ecx.rr;
ep->numFunctions = bb.edx.r.h;
ep->u_resources.d = bb.edx.r.l;
u.data[0] = bb.edi.r.l;
u.data[1] = bb.edi.r.h;
u.data[2] = bb.esi.r.l;
u.data[3] = bb.esi.r.h;
ep->id[0] = u.s.char1 + ('A' - 1);
ep->id[1] = (u.s.char2l | (u.s.char2h << 3)) + ('A' - 1);
ep->id[2] = u.s.char3 + ('A' - 1);
ep->id[3] = hex[u.s.d1];
ep->id[4] = hex[u.s.d2];
ep->id[5] = hex[u.s.d3];
ep->id[6] = hex[u.s.d4];
ep->id[7] = 0;
return 0;
}
/*
int
ReadEISAFuncInfo(EISA_func_info_t *ep, int slot, int function)
{
bb.intno = 0x15;
bb.eax.r.h = 0xd8;
bb.eax.r.l = 0x01;
bb.ecx.r.l = slot;
bb.ecx.r.h = function;
bb.esi.rr = (unsigned int)ep->data;
bios(&bb);
if (bb.eax.r.h == 0) {
ep->slot = slot;
ep->function = function;
}
return bb.eax.r.h;
bb.intno = 0x15;
bb.eax.r.h = 0xd8;
bb.eax.r.l = 0x01;
bb.ecx.r.l = slot;
bb.ecx.r.h = function;
bb.esi.rr = (unsigned int)ep->data;
bios(&bb);
if (bb.eax.r.h == 0)
{
ep->slot = slot;
ep->function = function;
}
return bb.eax.r.h;
}
#endif /* EISA_SUPPORT */
int
ReadPCIBusInfo(PCI_bus_info_t *pp)
{
bb.intno = 0x1a;
bb.eax.r.h = 0xb1;
bb.eax.r.l = 0x01;
bios(&bb);
if ((bb.eax.r.h == 0) && (bb.edx.rx == PCI_SIGNATURE)) {
pp->BIOSPresent = 1;
pp->u_bus.d = bb.eax.r.l;
pp->majorVersion = bb.ebx.r.h;
pp->minorVersion = bb.ebx.r.l;
pp->maxBusNum = bb.ecx.r.l;
return 0;
}
return -1;
bb.intno = 0x1a;
bb.eax.r.h = 0xb1;
bb.eax.r.l = 0x01;
bios(&bb);
if ((bb.eax.r.h == 0) && (bb.edx.rx == PCI_SIGNATURE))
{
pp->BIOSPresent = 1;
pp->u_bus.d = bb.eax.r.l;
pp->majorVersion = bb.ebx.r.h;
pp->minorVersion = bb.ebx.r.l;
pp->maxBusNum = bb.ecx.r.l;
return 0;
}
return -1;
}
void sleep(int n)
while (time18() < endtime);
}
//==============================================================================
void delay(int ms)
{
bb.intno = 0x15;
trunk/i386/libsaio/pci.h
105105
106106
107107
108
108
109109
110110
111111
uint32_tsignature;// 0x24506E50 '$PnP'
uint8_trevision;//1
uint8_tlength;
uint16_toffset;
uint16_toffset;
uint8_tchecksum;
uint32_tidentifier;
uint16_tmanufacturer;
trunk/i386/libsaio/saio_types.h
7070
7171
7272
73
74
73
74
7575
7676
7777
......
7979
8080
8181
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101101
102
102103
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
119120
120121
121122
122123
123124
125
124126
125127
126128
......
131133
132134
133135
134
136
137
135138
136139
137140
......
172175
173176
174177
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
202205
203206
204207
typedef struct {
charplist[IO_CONFIG_DATA_SIZE];// buffer for plist
TagPtrdictionary;// buffer for xml dictionary
boolcanOverride;// flag to mark a dictionary can be overriden
TagPtrdictionary; // buffer for xml dictionary
boolcanOverride;// flag to mark a dictionary can be overriden
} config_file_t;
/*
*/
struct boot_drive_info {
struct drive_params {
unsigned short buf_size;
unsigned short info_flags;
unsigned long phys_cyls;
unsigned long phys_heads;
unsigned long phys_spt;
unsigned long long phys_sectors;
unsigned short phys_nbps;
unsigned short dpte_offset;
unsigned short dpte_segment;
unsigned short key;
unsigned char path_len;
unsigned char reserved1;
unsigned short reserved2;
unsigned char bus_type[4];
unsigned char interface_type[8];
unsigned char interface_path[8];
unsigned char dev_path[8];
unsigned char reserved3;
unsigned char checksum;
unsigned short buf_size;
unsigned short info_flags;
unsigned long phys_cyls;
unsigned long phys_heads;
unsigned long phys_spt;
unsigned long long phys_sectors;
unsigned short phys_nbps;
unsigned short dpte_offset;
unsigned short dpte_segment;
unsigned short key;
unsigned char path_len;
unsigned char reserved1;
unsigned short reserved2;
unsigned char bus_type[4];
unsigned char interface_type[8];
unsigned char interface_path[8];
unsigned char dev_path[8];
unsigned char reserved3;
unsigned char checksum;
} params;
struct drive_dpte {
unsigned short io_port_base;
unsigned short control_port_base;
unsigned char head_flags;
unsigned char vendor_info;
unsigned char irq : 4;
unsigned char irq_unused : 4;
unsigned char block_count;
unsigned char dma_channel : 4;
unsigned char dma_type : 4;
unsigned char pio_type : 4;
unsigned char pio_unused : 4;
unsigned short option_flags;
unsigned short reserved;
unsigned char revision;
unsigned char checksum;
} dpte;
unsigned short io_port_base;
unsigned short control_port_base;
unsigned char head_flags;
unsigned char vendor_info;
unsigned char irq : 4;
unsigned char irq_unused : 4;
unsigned char block_count;
unsigned char dma_channel : 4;
unsigned char dma_type : 4;
unsigned char pio_type : 4;
unsigned char pio_unused : 4;
unsigned short option_flags;
unsigned short reserved;
unsigned char revision;
unsigned char checksum;
} dpte;
} __attribute__((packed));
typedef struct boot_drive_info boot_drive_info_t;
struct driveInfo {
boot_drive_info_t di;
int uses_ebios;
int no_emulation;
int biosdev;
unsigned char data[16];
} FinderInfo;
struct BootVolume;
structBootVolume;
typedef struct BootVolume * BVRef;
typedef struct BootVolume * CICell;
#define BVSTRLEN 32
struct BootVolume {
BVRef next; /* list linkage pointer */
int biosdev; /* BIOS device number */
int type; /* device type (floppy, hd, network) */
unsigned int flags; /* attribute flags */
BVGetDescription description; /* BVGetDescription function */
int part_no; /* partition number (1 based) */
unsigned int part_boff; /* partition block offset */
unsigned int part_type; /* partition type */
unsigned int fs_boff; /* 1st block # of next read */
unsigned int fs_byteoff; /* Byte offset for read within block */
FSLoadFile fs_loadfile; /* FSLoadFile function */
FSReadFile fs_readfile; /* FSReadFile function */
FSGetDirEntry fs_getdirentry; /* FSGetDirEntry function */
FSGetFileBlock fs_getfileblock; /* FSGetFileBlock function */
FSGetUUID fs_getuuid; /* FSGetUUID function */
unsigned int bps; /* bytes per sector for this device */
char name[BVSTRLEN]; /* (name of partition) */
char type_name[BVSTRLEN]; /* (type of partition, eg. Apple_HFS) */
BVFree bv_free; /* BVFree function */
uint32_t modTime;
char label[BVSTRLEN]; /* partition volume label */
char altlabel[BVSTRLEN]; /* partition volume label */
bool filtered; /* newFilteredBVChain() will set to TRUE */
bool visible; /* will shown in the device list */
char OSVersion[8];
bool OSisServer; /* 1 = OS X server , 0 = OS X client */
bool OSisInstaller; /* 1 = OS X Install partition / recover partition , 0 = OS X Install */
BVRefnext;/* list linkage pointer */
intbiosdev;/* BIOS device number */
inttype;/* device type (floppy, hd, network) */
unsigned intflags;/* attribute flags */
BVGetDescriptiondescription;/* BVGetDescription function */
intpart_no;/* partition number (1 based) */
unsigned intpart_boff;/* partition block offset */
unsigned intpart_type;/* partition type */
unsigned intfs_boff;/* 1st block # of next read */
unsigned intfs_byteoff;/* Byte offset for read within block */
FSLoadFilefs_loadfile;/* FSLoadFile function */
FSReadFilefs_readfile;/* FSReadFile function */
FSGetDirEntryfs_getdirentry;/* FSGetDirEntry function */
FSGetFileBlockfs_getfileblock;/* FSGetFileBlock function */
FSGetUUIDfs_getuuid;/* FSGetUUID function */
unsigned intbps;/* bytes per sector for this device */
charname[BVSTRLEN];/* (name of partition) */
chartype_name[BVSTRLEN];/* (type of partition, eg. Apple_HFS) */
BVFreebv_free;/* BVFree function */
uint32_tmodTime;
charlabel[BVSTRLEN];/* partition volume label */
charaltlabel[BVSTRLEN];/* partition volume label */
boolfiltered;/* newFilteredBVChain() will set to TRUE */
boolvisible;/* will shown in the device list */
charOSVersion[8];
boolOSisServer;/* 1 = OS X server , 0 = OS X client */
boolOSisInstaller;/* 1 = OS X Install partition / recover partition , 0 = OS X Install */
};
trunk/i386/libsaio/msdos.c
152152
153153
154154
155
156
157
158
159
155160
156
157
158
159
160
161
162
161
162
163
164
165
166
167
168
163169
164170
165171
......
167173
168174
169175
170
171
172
176
177
178
173179
174180
175181
176182
177183
178
179
180
184
185
186
187
188
181189
182
183
190
191
192
193
184194
185195
186196
......
234244
235245
236246
247
248
249
250
237251
238252
239253
......
294308
295309
296310
297
311
298312
299313
300314
......
382396
383397
384398
385
386
399
400
387401
388402
389403
390404
391
392
405
406
393407
394408
395409
......
649663
650664
651665
652
666
667
668
669
670
653671
654672
655673
674
675
676
677
678
656679
657680
658681
......
685708
686709
687710
711
712
713
714
715
716
688717
689718
690719
......
692721
693722
694723
724
725
726
727
728
729
695730
696731
697732
......
739774
740775
741776
742
777
743778
744779
745780
......
747782
748783
749784
785
786
787
788
750789
751790
752791
......
759798
760799
761800
801
802
762803
804
763805
764806
765807
......
768810
769811
770812
771
813
772814
773815
774816
......
798840
799841
800842
843
844
845
846
801847
802848
803849
......
847893
848894
849895
850
851
852
896
897
898
853899
854
855
856
900
901
902
857903
858
859
860
904
905
906
861907
862
863
864
908
909
910
865911
866912
867913
......
874920
875921
876922
877
878
923
924
879925
880926
881927
......
885931
886932
887933
888
934
889935
890936
891937
892938
939
940
941
942
893943
894944
895945
......
908958
909959
910960
911
912
961
962
963
913964
965
966
967
968
914969
915970
916971
917
918
919
920
921
922
972
973
974
975
976
977
978
979
980
923981
924982
925
983
926984
927
985
928986
929987
930988
931989
932990
933991
992
993
994
995
934996
935
997
936998
937999
1000
9381001
9391002
9401003
......
9481011
9491012
9501013
951
1014
9521015
}
buf=malloc (512);
if (!buf)
{
return -1;
}
/*
* Read the boot sector of the filesystem, and then check the
* boot signature. If not a dos boot sector then error out.
*
* NOTE: 2048 is a maximum sector size in current...
*/
Seek(ih, 0);
Read(ih, (long)buf, 512);
* Read the boot sector of the filesystem, and then check the
* boot signature. If not a dos boot sector then error out.
*
* NOTE: 2048 is a maximum sector size in current...
*/
Seek(ih, 0);
Read(ih, (long)buf, 512);
bsp = (union bootsector *)buf;
b33 = (struct bpb33 *)bsp->bs33.bsBPB;
b710 = (struct bpb710 *)bsp->bs710.bsBPB;
/* We only work with 512, 1024, and 2048 byte sectors */
msdosbps = OSSwapLittleToHostInt16(b33->bpbBytesPerSec);
if ((msdosbps < 0x200) || (msdosbps & (msdosbps - 1)) || (msdosbps > 0x800))
/* We only work with 512, 1024, and 2048 byte sectors */
msdosbps = OSSwapLittleToHostInt16(b33->bpbBytesPerSec);
if ((msdosbps < 0x200) || (msdosbps & (msdosbps - 1)) || (msdosbps > 0x800))
{
free (buf);
return -1;
}
/* Check to make sure valid sectors per cluster */
spc = b33->bpbSecPerClust;
if ((spc == 0 ) || (spc & (spc - 1)))
/* Check to make sure valid sectors per cluster */
spc = b33->bpbSecPerClust;
if ((spc == 0 ) || (spc & (spc - 1)))
{
free (buf);
return -1;
if (OSSwapLittleToHostInt16(b50->bpbRootDirEnts) == 0) { /* It's FAT32 */
}
if (OSSwapLittleToHostInt16(b50->bpbRootDirEnts) == 0)
{
/* It's FAT32 */
if (memcmp(((struct extboot *)bsp->bs710.bsExt)->exFileSysType, "FAT32 ", 8))
{
free (buf);
char *cacheBuffer;
cacheBuffer = malloc(MSDOS_CACHE_BLOCKSIZE);
if (!cacheBuffer)
{
return -1;
}
CacheRead(ih, cacheBuffer, sectorOffset, MSDOS_CACHE_BLOCKSIZE, true);
bcopy(cacheBuffer + relOffset, buf, size);
free(cacheBuffer);
readOffset += ((uint64_t)*cluster * (uint64_t)msdosfatbits) / 8;
/* Read one sector of the FAT */
readSector(ih, readOffset, tmpbuf, 4);
if (readSector(ih, readOffset, tmpbuf, 4) != 0) return 0;
switch (msdosfatbits) {
case 32:
st->vfatchecksum = 0;
st->vfatnumber = 0;
st->nument++;
if ((!st->root16 &&st->nument * sizeof (struct direntry)>=msdosclustersize)
|| (st->root16 &&st->nument * sizeof (struct direntry)>=msdosbps))
if (((int)(!st->root16 &&st->nument * sizeof (struct direntry))>=msdosclustersize)
|| ((int)(st->root16 &&st->nument * sizeof (struct direntry))>=msdosbps))
st->nument = 0;
return dirp;
}
st->nument++;
if ((!st->root16 &&st->nument * sizeof (struct direntry)>=msdosclustersize)
|| (st->root16 &&st->nument * sizeof (struct direntry)>=msdosbps))
if (((int)(!st->root16 &&st->nument * sizeof (struct direntry))>=msdosclustersize)
|| ((int)(st->root16 &&st->nument * sizeof (struct direntry))>=msdosbps))
st->nument = 0;
}
}
st = (struct msdosdirstate *)(long) *dirIndex;
if (!st)
{
st=malloc (sizeof (*st));
st=malloc (sizeof (struct msdosdirstate));
if (!st)
{
return -1;
}
if (dirPath[0])
{
uint8_t *buf=malloc(msdosclustersize);
if (!buf)
{
free (st);
return -1;
}
dirp = getdirpfrompath (ih, dirPath, buf);
if (!dirp || !(dirp->deAttributes & ATTR_DIRECTORY))
{
int i;
for (i=0;vfatname[i];i++);
*name = malloc (256);
if (!*name)
{
free (st->buf);
free (st);
return -1;
}
utf_encodestr(vfatname, i, (u_int8_t *)*name, 255, OSLittleEndian );
}
else
int i, j, k;
uint16_t tmp[13];
*name = malloc (26);
if (!*name)
{
free (st->buf);
free (st);
return -1;
}
for (i=7;i>=0;i--)
if (dirp->deName[i]!=' ')
break;
int toread, wastoread;
char *ptr = (char *)base;
struct direntry *dirp;
int i;
uint64_t i;
char devStr[12];
if (MSDOSInitPartition (ih)<0)
if (filePath[0] == '/')
filePath++;
buf = malloc(msdosclustersize);
if (!buf)
{
return -1;
}
dirp = getdirpfrompath (ih, filePath, buf);
if (!dirp || (dirp->deAttributes & ATTR_DIRECTORY))
cluster |= ((uint32_t)OSReadLittleInt16 ((dirp->deHighClust),0)) <<16;
size = (uint32_t)OSReadLittleInt32 ((dirp->deFileSize),0);
if (size<=offset)
{
free (buf);
return -1;
}
nskip=offset/msdosclustersize;
for (i=0;i<nskip;i++)
msdosreadcluster (ih, 0, 0, &cluster);
if (length==0 || length>size-offset)
toread=size-offset;
wastoread=toread;
bcopy (buf+(offset%msdosclustersize),ptr,MIN(msdosclustersize-(offset%msdosclustersize), toread));
bcopy (buf+(offset%msdosclustersize),ptr,MIN((msdosclustersize-(offset%msdosclustersize)),(unsigned)toread));
ptr+=msdosclustersize-(offset%msdosclustersize);
toread-=msdosclustersize-(offset%msdosclustersize);
while (toread>0 && msdosreadcluster (ih, (uint8_t *)ptr, MIN(msdosclustersize,toread), &cluster))
if (filePath[0] == '/')
filePath++;
buf = malloc(msdosclustersize);
if (!buf)
{
return -1;
}
dirp = getdirpfrompath (ih, filePath, buf);
if (!dirp || (dirp->deAttributes & ATTR_DIRECTORY))
{
static void
fixLabel(uint8_t *label, char *str, long strMaxLen)
{
inti, len;
uint16_tlabelucs[13];
//unsigned charlabelUTF8[LABEL_LENGTH*3];
inti, len;
uint16_tlabelucs[13];
//unsigned charlabelUTF8[LABEL_LENGTH*3];
/* Convert leading 0x05 to 0xE5 for multibyte languages like Japanese */
if (label[0] == 0x05)
label[0] = 0xE5;
/* Convert leading 0x05 to 0xE5 for multibyte languages like Japanese */
if (label[0] == 0x05)
label[0] = 0xE5;
/* Remove any trailing spaces */
for (i=LABEL_LENGTH-1; i>=0; --i) {
if (label[i] == ' ')
/* Remove any trailing spaces */
for (i=LABEL_LENGTH-1; i>=0; --i) {
if (label[i] == ' ')
label[i] = 0;
else
break;
}
else
break;
}
labelucs[i++]=0;
len=i;
for (;i>=0;--i)
void
MSDOSGetDescription(CICell ih, char *str, long strMaxLen)
{
struct direntry *dirp;
uint8_t label[LABEL_LENGTH+1];
struct direntry*dirp;
uint8_tlabel[LABEL_LENGTH+1];
uint16_tvfatlabel[WIN_MAXLEN+2*WIN_CHARS];
struct msdosdirstate st;
int labelfound = 0;
str[0]=0;
return;
}
label[0] = '\0';
initRoot (&st);
st.buf = malloc(msdosclustersize);
if (!st.buf)
{
return;
}
while ((dirp = getnextdirent (ih, vfatlabel, &st)))
if (dirp->deAttributes & ATTR_VOLUME) {
strncpy((char *)label, (char *)dirp->deName, LABEL_LENGTH);
else if (labelfound)
fixLabel(label, str, strMaxLen);
/* else look in the boot blocks */
if (!labelfound || str[0] == '\0') {
/* else look in the boot blocks */
if (!labelfound || str[0] == '\0')
{
char *buf = malloc (512);
if (!buf)
{
return;
}
union bootsector *bsp = (union bootsector *)buf;
Seek(ih, 0);
Read(ih, (long)buf, 512);
if (msdosfatbits == 32) { /* It's FAT32 */
strncpy((char *)label, (char *)((struct extboot *)bsp->bs710.bsExt)->exVolumeLabel, LABEL_LENGTH);
}
else if (msdosfatbits == 16) {
strncpy((char *)label, (char *)((struct extboot *)bsp->bs50.bsExt)->exVolumeLabel, LABEL_LENGTH);
}
if (msdosfatbits == 32)
{
/* It's FAT32 */
strncpy((char *)label, (char *)((struct extboot *)bsp->bs710.bsExt)->exVolumeLabel, LABEL_LENGTH);
}
else if (msdosfatbits == 16)
{
strncpy((char *)label, (char *)((struct extboot *)bsp->bs50.bsExt)->exVolumeLabel, LABEL_LENGTH);
}
free (buf);
fixLabel(label, str, strMaxLen);
}
}
return;
return;
}
long
MSDOSGetUUID(CICell ih, char *uuidStr)
{
char *buf = malloc (512);
if (!buf)
{
return -1;
}
union bootsector *bsp = (union bootsector *)buf;
if (MSDOSInitPartition (ih)<0)
{
free (buf);
return -1;
}
bzero (uuidStr, 16);
}
free (buf);
return 0;
}
trunk/i386/libsaio/saio_internal.h
218218
219219
220220
221
221
222222
223223
224224
unsigned int byteoff,
unsigned int byteCount, void * buffer );
/* Base64-decode.c */
// Base64-decode.c
char *BASE64Decode(const char* src, int in_len, int* out_len);
#endif /* !__LIBSAIO_SAIO_INTERNAL_H */
trunk/i386/boot2/picopng.c
11041104
11051105
11061106
1107
1108
1109
1110
1111
1112
1107
1108
1109
1110
1111
1112
11131113
1114
1115
1114
1115
11161116
11171117
11181118
}
insize = (uint32_t) statbuf.st_size;
inbuf = malloc(insize);
if (!inbuf) {
perror("malloc");
fclose(infp);
return 1;
}
if (fread(inbuf, 1, insize, infp) != insize) {
if (!inbuf) {
perror("malloc");
fclose(infp);
return 1;
}
if (fread(inbuf, 1, insize, infp) != insize) {
perror("fread");
free(inbuf);
fclose(infp);
free(inbuf);
fclose(infp);
return 1;
}
fclose(infp);
trunk/i386/boot2/graphics.c
8484
8585
8686
87
88
89
87
88
89
9090
9191
9292
......
106106
107107
108108
109
110
111
112
113
114
109
110
111
112
113
114
115115
116116
117
118
119
120
117
118
119
120
121
121122
122
123
123124
124
125
126
127
125
126
127
128
128129
129
130
131
132
133
134
135
136
130
131
132
133
134
135
136
137
137138
138139
139140
140
141
141142
142
143
143144
144
145
145
146
146147
147
148
149
150
151
152
148
149
150
151
152
153
153154
154
155
156
157
155
156
157
158
158159
159
160
161
162
163
164
165
166
167
168
169
160
161
162
163
164
165
166
167
168
169
170
170171
171172
172173
173174
174175
175
176
177
176
177
178
178179
179180
180
181
182
183
184
181
182
183
184
185
185186
186
187
187
188
189
188190
191
192
189193
190
191
192
193
194
194
195
196
197
198
195199
196
197
198
199
200
201
200
201
202
203
204
202205
203
204
205
206
207
208
209
206
207
208
209
210
211
210212
211213
212214
return 0;
buff = malloc(sizeof(char) * 256);
if (!buff)
return 0;
if (!buff) {
return 0;
}
small = (vbeInfo.TotalMemory < 16);
snprintf(buff, 256,
void
printVBEModeInfo()
{
VBEInfoBlock vbeInfo;
unsigned short * modePtr;
VBEModeInfoBlock modeInfo;
int err;
int line;
char* vbeInfoString = NULL;
VBEInfoBlock vbeInfo;
unsigned short * modePtr;
VBEModeInfoBlock modeInfo;
int err;
int line;
char* vbeInfoString = NULL;
bzero( &vbeInfo, sizeof(vbeInfo) );
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if ( err != errSuccess )
return;
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if ( err != errSuccess ) {
return;
}
line = 0;
line = 0;
// Activate and clear page 1
setActiveDisplayPage(1);
clearScreenRows(0, 24);
setCursorPosition( 0, 0, 1 );
// Activate and clear page 1
setActiveDisplayPage(1);
clearScreenRows(0, 24);
setCursorPosition( 0, 0, 1 );
vbeInfoString = getVBEInfoString();
if (!vbeInfoString) {
printf("Error: getVBEInfoString failed\n");
return;
}
printf("%s", vbeInfoString);
free(vbeInfoString);
vbeInfoString = NULL;
vbeInfoString = getVBEInfoString();
if (!vbeInfoString) {
printf("Error: getVBEInfoString failed\n");
return;
}
printf("%s", vbeInfoString);
free(vbeInfoString);
vbeInfoString = NULL;
printf("Video modes supported:\n", VBEDecodeFP(const char *, vbeInfo.OEMStringPtr));
// Loop through the mode list, and find the matching mode.
// Loop through the mode list, and find the matching mode.
for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
*modePtr != modeEndOfList; modePtr++ )
{
// Get mode information.
{
// Get mode information.
bzero( &modeInfo, sizeof(modeInfo) );
err = getVBEModeInfo( *modePtr, &modeInfo );
if ( err != errSuccess )
{
continue;
}
bzero( &modeInfo, sizeof(modeInfo) );
err = getVBEModeInfo( *modePtr, &modeInfo );
if ( err != errSuccess )
{
continue;
}
printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
modeInfo.ModeAttributes);
printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
modeInfo.ModeAttributes);
if (line++ >= 20) {
pause();
line = 0;
clearScreenRows(0, 24);
setCursorPosition( 0, 0, 1 );
}
}
if (line != 0) {
pause();
}
setActiveDisplayPage(0);
if (line++ >= 20) {
pause();
line = 0;
clearScreenRows(0, 24);
setCursorPosition( 0, 0, 1 );
}
}
if (line != 0) {
pause();
}
setActiveDisplayPage(0);
}
char *getVBEModeInfoString()
{
VBEInfoBlock vbeInfo;
unsigned short * modePtr;
VBEModeInfoBlock modeInfo;
int err;
unsigned short * modePtr;
VBEModeInfoBlock modeInfo;
int err;
bzero( &vbeInfo, sizeof(vbeInfo) );
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if ( err != errSuccess )
return 0;
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if ( err != errSuccess ) {
return 0;
}
char *buff=malloc(sizeof(char)*3072);
if(!buff) return 0;
int bufflen = 0;
if(!buff) {
return 0;
}
int bufflen = 0;
// Loop through the mode list, and find the matching mode.
for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
(*modePtr != modeEndOfList) && (bufflen < 3072); /* prevent buffer overrun */
modePtr++ )
{
// Get mode information.
for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
(*modePtr != modeEndOfList) && (bufflen < 3072); /* prevent buffer overrun */
modePtr++ )
{
// Get mode information.
bzero( &modeInfo, sizeof(modeInfo) );
err = getVBEModeInfo( *modePtr, &modeInfo );
if ( err != errSuccess )
{
continue;
}
bzero( &modeInfo, sizeof(modeInfo) );
err = getVBEModeInfo( *modePtr, &modeInfo );
if ( err != errSuccess ) {
continue;
}
bufflen +=
snprintf(buff+bufflen, 3072-bufflen, "Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
modeInfo.ModeAttributes);
}
bufflen +=
snprintf(buff+bufflen, 3072-bufflen, "Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
modeInfo.ModeAttributes);
}
return buff;
}
trunk/i386/boot2/drivers.c
4343
4444
4545
46
47
48
49
50
51
52
53
46
47
48
49
50
51
52
53
5454
5555
5656
5757
58
59
60
61
62
63
58
59
60
61
62
63
6464
6565
6666
......
8080
8181
8282
83
84
83
84
8585
8686
8787
......
114114
115115
116116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
117
118
134119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135135
136136
137137
......
147147
148148
149149
150
151
152
153
154
150
151
152
153
154
155155
156
157
156
157
158
158159
159
160
160161
161162
162163
......
164165
165166
166167
167
168
168169
169
170
170
171
172
171173
172
173
174
175
176
174
175
176
177
178
177179
178
179
180
181
182
183
184
185
180
186181
187
188
189
190
191
192
182
183
184
185
186
187
188
189
190
191
192
193
194
195
193196
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
246238
247
239
248240
249241
250242
251
252
253
254
243
244
245
246
255247
256
257
258
259
260
261
248
249
250
251
262252
263
253
264254
265
255
266256
267
257
268258
269
259
270260
271261
272262
......
289279
290280
291281
292
282
293283
294284
295
285
296286
287
297288
298289
299290
......
305296
306297
307298
308
309
310
311
312
313
314
315
316
317
299
300
301
302
318303
319
320
321
304
305
306
307
308
309
322310
323
324
311
312
313
314
325315
326
327
328
329
316
317
330318
331
332
333
334
335
336
319
320
321
322
323
324
325
337326
338
339
340
341
342
343
344
345
327
328
329
330
346331
347
348
349
332
333
334
335
336
350337
351
338
339
352340
353
354
341
342
343
344
345
346
347
348
355349
356
357
358
350
351
352
359353
360
354
355
356
357
358
359
360
361
362
363
364
365
361366
362367
363368
......
367372
368373
369374
370
375
371376
372377
373
378
374379
375
376
377
378
379
380
381
382
380
381
382
383
384
385
386
387
383388
384389
385
386
390
391
387392
388
393
389394
390
391
392
393
394
395
395
396
397
398
399
400
401
402
403
404
396405
397406
398407
......
403412
404413
405414
406
407
408
409
415
416
417
418
410419
411420
412421
413
414
415
422
423
424
425
426
416427
417428
418429
419430
420431
421
422
423
424
425
426
427
428
429
432
433
434
435
436
437
438
439
440
430441
431
432
433
442
443
444
434445
435
436
446
447
437448
438
439
440
441
449
450
451
442452
443
453
444454
445455
446456
......
449459
450460
451461
452
453
454
455
456
457
458
462
463
464
465
466
467
468
459469
460
461
470
471
462472
463
464
465
466
467
468
469
473
474
475
476
477
478
470479
471
472
473
474
475
476
477
478
479
480
481
482
483
484
480485
481
482
486
487
488
489
490
491
483492
484
493
494
495
496
485497
486
498
487499
488
489
490
491
492
493
500
494501
495
496
497
498
499
500
502
503
504
505
506
501507
502
508
509
510
511
512
513
514
515
516
517
503518
504
505
506
519
507520
508
509
510
511
512
513
514
515
516
517
518
521
519522
520
523
524
525
526
521527
522
523
524
525
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
526548
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
546572
547
548
549
573
574
575
550576
551
552
553
554
555
577
578
579
580
581
582
583
584
585
586
556587
557588
558589
......
652683
653684
654685
655
656
686
687
657688
658689
659690
......
662693
663694
664695
665
666
667
696
697
698
668699
669
670
671
700
701
702
672703
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
704709
705
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
706744
707745
708746
......
713751
714752
715753
716
717
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
718769
719
720
721
722
723
724
725
726
727
728
770
729771
730772
731773
......
739781
740782
741783
742
784
743785
744
745
746
747
748
749
750
751
752
753
754
755
756
757
786
787
788
789
790
791
758792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
759808
760809
761810
......
764813
765814
766815
767
768
769
770
771
772
773
816
817
818
819
820
821
774822
775
823
776824
777
825
778826
779
827
780828
781
829
782830
783
831
784832
785
833
786834
787835
788836
789837
790838
791839
792
840
793841
794842
795843
......
845893
846894
847895
848
849
850
851
852
853
854
896
897
898
899
900
901
902
855903
856
857
858
859
860
861
862
863
864
865
904
905
906
907
908
909
910
911
912
866913
//extern char gMacOSVersion[8];
struct Module {
struct Module *nextModule;
long willLoad;
TagPtr dict;
char *plistAddr;
long plistLength;
char *executablePath;
char *bundlePath;
long bundlePathLength;
struct Module *nextModule;
long willLoad;
TagPtr dict;
char *plistAddr;
long plistLength;
char *executablePath;
char *bundlePath;
long bundlePathLength;
};
typedef struct Module Module, *ModulePtr;
struct DriverInfo {
char *plistAddr;
long plistLength;
void *executableAddr;
long executableLength;
void *bundlePathAddr;
long bundlePathLength;
char *plistAddr;
long plistLength;
void *executableAddr;
long executableLength;
void *bundlePathAddr;
long bundlePathLength;
};
typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
typedef struct DriversPackage DriversPackage;
enum {
kCFBundleType2,
kCFBundleType3
kCFBundleType2,
kCFBundleType3
};
long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);
/*static*/ unsigned long
Adler32( unsigned char * buffer, long length )
{
long cnt;
unsigned long result, lowHalf, highHalf;
lowHalf = 1;
highHalf = 0;
for ( cnt = 0; cnt < length; cnt++ )
{
if ((cnt % 5000) == 0)
{
lowHalf %= 65521L;
highHalf %= 65521L;
}
lowHalf += buffer[cnt];
highHalf += lowHalf;
}
long cnt;
unsigned long result, lowHalf, highHalf;
lowHalf = 1;
highHalf = 0;
for (cnt = 0; cnt < length; cnt++)
{
if ((cnt % 5000) == 0)
{
lowHalf %= 65521L;
highHalf %= 65521L;
}
lowHalf += buffer[cnt];
highHalf += lowHalf;
}
lowHalf %= 65521L;
highHalf %= 65521L;
static long
InitDriverSupport( void )
{
gExtensionsSpec = malloc( 4096 );
gDriverSpec = malloc( 4096 );
gFileSpec = malloc( 4096 );
gTempSpec = malloc( 4096 );
gFileName = malloc( 4096 );
gExtensionsSpec = malloc( 4096 );
gDriverSpec = malloc( 4096 );
gFileSpec = malloc( 4096 );
gTempSpec = malloc( 4096 );
gFileName = malloc( 4096 );
if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName )
stop("InitDriverSupport error");
if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName ) {
stop("InitDriverSupport error");
}
return 0;
return 0;
}
//==========================================================================
long LoadDrivers( char * dirSpec )
{
char dirSpecExtra[1024];
char dirSpecExtra[1024];
if ( InitDriverSupport() != 0 )
return 0;
if ( InitDriverSupport() != 0 ) {
return 0;
}
// Load extra drivers if a hook has been installed.
if (LoadExtraDrivers_p != NULL)
{
(*LoadExtraDrivers_p)(&FileLoadDrivers);
}
// Load extra drivers if a hook has been installed.
if (LoadExtraDrivers_p != NULL)
{
(*LoadExtraDrivers_p)(&FileLoadDrivers);
}
if ( gBootFileType == kNetworkDeviceType )
{
if (NetLoadDrivers(dirSpec) != 0) {
error("Could not load drivers from the network\n");
return -1;
}
}
else if ( gBootFileType == kBlockDeviceType )
if ( gBootFileType == kNetworkDeviceType )
{
// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).
if (gRAMDiskVolume && !gRAMDiskBTAliased)
{
strcpy(dirSpecExtra, "rd(0,0)/Extra/");
FileLoadDrivers(dirSpecExtra, 0);
}
if (NetLoadDrivers(dirSpec) != 0)
{
error("Could not load drivers from the network\n");
return -1;
}
}
else if ( gBootFileType == kBlockDeviceType )
{
// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).
if (gRAMDiskVolume && !gRAMDiskBTAliased)
{
strcpy(dirSpecExtra, "rd(0,0)/Extra/");
FileLoadDrivers(dirSpecExtra, 0);
}
// Next try to load Extra extensions from the selected root partition.
strcpy(dirSpecExtra, "/Extra/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0)
{
// If failed, then try to load Extra extensions from the boot partition
// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.
if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)
|| (gRAMDiskVolume && gRAMDiskBTAliased) )
{
// Next try a specfic OS version folder ie 10.5
sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);
if (FileLoadDrivers(dirSpecExtra, 0) != 0)
{
// Next we'll try the base
strcpy(dirSpecExtra, "bt(0,0)/Extra/");
FileLoadDrivers(dirSpecExtra, 0);
}
}
}
if(!gHaveKernelCache)
{
// Don't load main driver (from /System/Library/Extentions) if gHaveKernelCache is set.
// since these drivers will already be in the kernel cache.
// NOTE: when gHaveKernelCache, xnu cannot (by default) load *any* extra kexts from the bootloader.
// The /Extra code is not disabled in this case due to a kernel patch that allows for this to happen.
// Also try to load Extensions from boot helper partitions.
if (gBootVolume->flags & kBVFlagBooter)
{
strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0)
{
strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0)
{
strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");
FileLoadDrivers(dirSpecExtra, 0);
}
}
}
if (gMKextName[0] != '\0')
{
verbose("LoadDrivers: Loading from [%s]\n", gMKextName);
if ( LoadDriverMKext(gMKextName) != 0 )
{
error("Could not load %s\n", gMKextName);
return -1;
}
}
else
{
// Next try to load Extra extensions from the selected root partition.
strcpy(dirSpecExtra, "/Extra/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0) {
// If failed, then try to load Extra extensions from the boot partition
// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.
if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)
|| (gRAMDiskVolume && gRAMDiskBTAliased) ) {
// Next try a specfic OS version folder ie 10.5
sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);
if (FileLoadDrivers(dirSpecExtra, 0) != 0) {
// Next we'll try the base
strcpy(dirSpecExtra, "bt(0,0)/Extra/");
FileLoadDrivers(dirSpecExtra, 0);
}
}
}
if(!gHaveKernelCache) {
// Don't load main driver (from /System/Library/Extentions) if gHaveKernelCache is set.
// since these drivers will already be in the kernel cache.
// NOTE: when gHaveKernelCache, xnu cannot (by default) load *any* extra kexts from the bootloader.
// The /Extra code is not disabled in this case due to a kernel patch that allows for this to happen.
// Also try to load Extensions from boot helper partitions.
if (gBootVolume->flags & kBVFlagBooter) {
strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0) {
strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0) {
strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");
FileLoadDrivers(dirSpecExtra, 0);
}
}
}
if (gMKextName[0] != '\0') {
verbose("LoadDrivers: Loading from [%s]\n", gMKextName);
if ( LoadDriverMKext(gMKextName) != 0 ) {
error("Could not load %s\n", gMKextName);
return -1;
}
} else {
if (gMacOSVersion[3] == '9') {
strlcpy(gExtensionsSpec, dirSpec, 4087); /* 4096 - sizeof("Library/") */
strlcpy(gExtensionsSpec, dirSpec, 4087); /* 4096 - sizeof("Library/") */
strcat(gExtensionsSpec, "Library/");
FileLoadDrivers(gExtensionsSpec, 0);
}
strlcpy(gExtensionsSpec, dirSpec, 4080); /* 4096 - sizeof("System/Library/") */
strcat(gExtensionsSpec, "System/Library/");
FileLoadDrivers(gExtensionsSpec, 0);
}
strlcpy(gExtensionsSpec, dirSpec, 4080); /* 4096 - sizeof("System/Library/") */
strcat(gExtensionsSpec, "System/Library/");
FileLoadDrivers(gExtensionsSpec, 0);
}
}
}
else
{
return 0;
}
}
} else {
return 0;
}
MatchPersonalities();
MatchPersonalities();
MatchLibraries();
MatchLibraries();
LoadMatchedModules();
LoadMatchedModules();
return 0;
return 0;
}
//==========================================================================
|| ((flags & kFileTypeMask) != kFileTypeDirectory)
|| (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
{
snprintf(gDriverSpec, sizeof(altDirSpec) + 18, "%sExtensions.mkext", altDirSpec);
snprintf(gDriverSpec, sizeof(altDirSpec) + 18, "%sExtensions.mkext", altDirSpec);
verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);
if (LoadDriverMKext(gDriverSpec) == 0)
if (LoadDriverMKext(gDriverSpec) == 0) {
return 0;
}
}
}
return -1;
long
FileLoadDrivers( char * dirSpec, long plugin )
{
long ret, length, flags, time, bundleType;
long long index;
long result = -1;
const char * name;
if ( !plugin )
{
// First try 10.6's path for loading Extensions.mkext.
if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0)
return 0;
long ret, length, flags, time, bundleType;
long long index;
long result = -1;
const char * name;
// Next try the legacy path.
else if (FileLoadMKext(dirSpec, "") == 0)
return 0;
if ( !plugin )
{
// First try 10.6's path for loading Extensions.mkext.
if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0) {
return 0;
}
strcat(dirSpec, "Extensions");
}
// Next try the legacy path.
else if (FileLoadMKext(dirSpec, "") == 0) {
return 0;
}
index = 0;
while (1) {
ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
if (ret == -1) break;
strcat(dirSpec, "Extensions");
}
// Make sure this is a directory.
if ((flags & kFileTypeMask) != kFileTypeDirectory) continue;
// Make sure this is a kext.
length = strlen(name);
if (strcmp(name + length - 5, ".kext")) continue;
index = 0;
while (1)
{
ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
if (ret == -1) {
break;
}
// Save the file name.
strlcpy(gFileName, name, 4096);
// Determine the bundle type.
snprintf(gTempSpec, 4096, "%s/%s", dirSpec, gFileName);
ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);
if (ret == 0) bundleType = kCFBundleType2;
else bundleType = kCFBundleType3;
// Make sure this is a directory.
if ((flags & kFileTypeMask) != kFileTypeDirectory) {
continue;
}
if (!plugin)
snprintf(gDriverSpec, 4096, "%s/%s/%sPlugIns", dirSpec, gFileName,
(bundleType == kCFBundleType2) ? "Contents/" : "");
// Make sure this is a kext.
length = strlen(name);
if (strcmp(name + length - 5, ".kext")) {
continue;
}
ret = LoadDriverPList(dirSpec, gFileName, bundleType);
// Save the file name.
strlcpy(gFileName, name, 4096);
if (result != 0)
result = ret;
// Determine the bundle type.
snprintf(gTempSpec, 4096, "%s/%s", dirSpec, gFileName);
ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);
if (ret == 0) {
bundleType = kCFBundleType2;
} else {
bundleType = kCFBundleType3;
}
if (!plugin)
FileLoadDrivers(gDriverSpec, 1);
}
if (!plugin) {
snprintf(gDriverSpec, 4096, "%s/%s/%sPlugIns", dirSpec, gFileName, (bundleType == kCFBundleType2) ? "Contents/" : "");
}
return result;
ret = LoadDriverPList(dirSpec, gFileName, bundleType);
if (result != 0) {
result = ret;
}
if (!plugin) {
FileLoadDrivers(gDriverSpec, 1);
}
}
return result;
}
long
NetLoadDrivers( char * dirSpec )
{
long tries;
long tries;
#if NODEF
long cnt;
long cnt;
// Get the name of the kernel
cnt = strlen(gBootFile);
while (cnt--) {
if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ',')) {
cnt++;
break;
}
}
// Get the name of the kernel
cnt = strlen(gBootFile);
while (cnt--) {
if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ',')) {
cnt++;
break;
}
}
#endif
// INTEL modification
snprintf(gDriverSpec, 4096, "%s%s.mkext", dirSpec, bootInfo->bootFile);
// INTEL modification
snprintf(gDriverSpec, 4096, "%s%s.mkext", dirSpec, bootInfo->bootFile);
verbose("NetLoadDrivers: Loading from [%s]\n", gDriverSpec);
verbose("NetLoadDrivers: Loading from [%s]\n", gDriverSpec);
tries = 3;
while (tries--)
{
if (LoadDriverMKext(gDriverSpec) == 0) break;
}
if (tries == -1) return -1;
tries = 3;
while (tries--)
{
if (LoadDriverMKext(gDriverSpec) == 0) {
break;
}
}
if (tries == -1) {
return -1;
}
return 0;
}
long
LoadDriverMKext( char * fileSpec )
{
unsigned long driversAddr, driversLength;
long length;
char segName[32];
DriversPackage * package;
unsigned long driversAddr, driversLength;
long length;
char segName[32];
DriversPackage * package;
#define GetPackageElement(e) OSSwapBigToHostInt32(package->e)
// Load the MKext.
length = LoadThinFatFile(fileSpec, (void **)&package);
if (length < sizeof (DriversPackage)) return -1;
// Load the MKext.
length = LoadThinFatFile(fileSpec, (void **)&package);
if (length < sizeof (DriversPackage)) {
return -1;
}
// call hook to notify modules that the mkext has been loaded
execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) &length, NULL);
// Verify the MKext.
if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
( GetPackageElement(signature2) != kDriverPackageSignature2) ||
( GetPackageElement(length) > kLoadSize ) ||
( GetPackageElement(adler32) !=
Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
{
return -1;
}
// Verify the MKext.
if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
( GetPackageElement(signature2) != kDriverPackageSignature2) ||
( GetPackageElement(length) > kLoadSize ) ||
( GetPackageElement(adler32) !=
Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
{
return -1;
}
// Make space for the MKext.
driversLength = GetPackageElement(length);
driversAddr = AllocateKernelMemory(driversLength);
// Make space for the MKext.
driversLength = GetPackageElement(length);
driversAddr = AllocateKernelMemory(driversLength);
// Copy the MKext.
memcpy((void *)driversAddr, (void *)package, driversLength);
// Copy the MKext.
memcpy((void *)driversAddr, (void *)package, driversLength);
// Add the MKext to the memory map.
snprintf(segName, sizeof(segName), "DriversPackage-%lx", driversAddr);
AllocateMemoryRange(segName, driversAddr, driversLength,
kBootDriverTypeMKEXT);
// Add the MKext to the memory map.
snprintf(segName, sizeof(segName), "DriversPackage-%lx", driversAddr);
AllocateMemoryRange(segName, driversAddr, driversLength, kBootDriverTypeMKEXT);
return 0;
return 0;
}
//==========================================================================
long
LoadDriverPList( char * dirSpec, char * name, long bundleType )
{
long length, executablePathLength, bundlePathLength;
ModulePtr module;
TagPtr personalities;
char * buffer = 0;
char * tmpExecutablePath = 0;
char * tmpBundlePath = 0;
long ret = -1;
long length, executablePathLength, bundlePathLength;
ModulePtr module;
TagPtr personalities;
char * buffer = 0;
char * tmpExecutablePath = 0;
char * tmpBundlePath = 0;
long ret = -1;
do {
// Save the driver path.
do{
// Save the driver path.
if(name)
snprintf(gFileSpec, 4096, "%s/%s/%s", dirSpec, name,
(bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
else
snprintf(gFileSpec, 4096, "%s/%s", dirSpec,
(bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
executablePathLength = strlen(gFileSpec) + 1;
if(name) {
snprintf(gFileSpec, 4096, "%s/%s/%s", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
} else {
snprintf(gFileSpec, 4096, "%s/%s", dirSpec, (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
}
executablePathLength = strlen(gFileSpec) + 1;
tmpExecutablePath = malloc(executablePathLength);
if (tmpExecutablePath == 0) break;
strcpy(tmpExecutablePath, gFileSpec);
if(name)
snprintf(gFileSpec, 4096, "%s/%s", dirSpec, name);
else
snprintf(gFileSpec, 4096, "%s", dirSpec);
bundlePathLength = strlen(gFileSpec) + 1;
tmpExecutablePath = malloc(executablePathLength);
if (tmpExecutablePath == 0) {
break;
}
strcpy(tmpExecutablePath, gFileSpec);
tmpBundlePath = malloc(bundlePathLength);
if (tmpBundlePath == 0) break;
if(name) {
snprintf(gFileSpec, 4096, "%s/%s", dirSpec, name);
} else {
snprintf(gFileSpec, 4096, "%s", dirSpec);
}
bundlePathLength = strlen(gFileSpec) + 1;
strcpy(tmpBundlePath, gFileSpec);
tmpBundlePath = malloc(bundlePathLength);
if (tmpBundlePath == 0) {
break;
}
// Construct the file spec to the plist, then load it.
strcpy(tmpBundlePath, gFileSpec);
if(name)
snprintf(gFileSpec, 4096, "%s/%s/%sInfo.plist", dirSpec, name,
(bundleType == kCFBundleType2) ? "Contents/" : "");
else
snprintf(gFileSpec, 4096, "%s/%sInfo.plist", dirSpec,
(bundleType == kCFBundleType2) ? "Contents/" : "");
// Construct the file spec to the plist, then load it.
length = LoadFile(gFileSpec);
if (length == -1) break;
length = length + 1;
buffer = malloc(length);
if (buffer == 0) break;
strlcpy(buffer, (char *)kLoadAddr, length);
if(name) {
snprintf(gFileSpec, 4096, "%s/%s/%sInfo.plist", dirSpec, name, (bundleType == kCFBundleType2) ? "Contents/" : "");
} else {
snprintf(gFileSpec, 4096, "%s/%sInfo.plist", dirSpec, (bundleType == kCFBundleType2) ? "Contents/" : "");
}
// Parse the plist.
length = LoadFile(gFileSpec);
if (length == -1) {
break;
}
length = length + 1;
buffer = malloc(length);
if (buffer == 0) {
break;
}
strlcpy(buffer, (char *)kLoadAddr, length);
ret = ParseXML(buffer, &module, &personalities);
if (ret != 0) { break; }
// Allocate memory for the driver path and the plist.
// Parse the plist.
module->executablePath = tmpExecutablePath;
module->bundlePath = tmpBundlePath;
module->bundlePathLength = bundlePathLength;
module->plistAddr = malloc(length);
if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))
break;
// Save the driver path in the module.
//strcpy(module->driverPath, tmpDriverPath);
tmpExecutablePath = 0;
tmpBundlePath = 0;
ret = ParseXML(buffer, &module, &personalities);
// Add the plist to the module.
if (ret != 0) {
break;
}
// Allocate memory for the driver path and the plist.
strlcpy(module->plistAddr, (char *)kLoadAddr, length);
module->plistLength = length;
// Add the module to the end of the module list.
module->executablePath = tmpExecutablePath;
module->bundlePath = tmpBundlePath;
module->bundlePathLength = bundlePathLength;
module->plistAddr = malloc(length);
if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0)) {
break;
}
// Save the driver path in the module.
//strcpy(module->driverPath, tmpDriverPath);
tmpExecutablePath = 0;
tmpBundlePath = 0;
// Add the plist to the module.
strlcpy(module->plistAddr, (char *)kLoadAddr, length);
module->plistLength = length;
// Add the module to the end of the module list.
if (gModuleHead == 0)
gModuleHead = module;
else
gModuleTail->nextModule = module;
gModuleTail = module;
// Add the persionalities to the personality list.
if (personalities) personalities = personalities->tag;
while (personalities != 0)
{
if (gPersonalityHead == 0)
gPersonalityHead = personalities->tag;
else
gPersonalityTail->tagNext = personalities->tag;
gPersonalityTail = personalities->tag;
personalities = personalities->tagNext;
}
if (gModuleHead == 0) {
gModuleHead = module;
} else {
gModuleTail->nextModule = module;
}
gModuleTail = module;
// Add the persionalities to the personality list.
if (personalities) {
personalities = personalities->tag;
}
while (personalities != 0)
{
if (gPersonalityHead == 0) {
gPersonalityHead = personalities->tag;
} else {
gPersonalityTail->tagNext = personalities->tag;
}
gPersonalityTail = personalities->tag;
personalities = personalities->tagNext;
}
ret = 0;
}
while (0);
ret = 0;
}
while (0);
if ( buffer ) free( buffer );
if ( tmpExecutablePath ) free( tmpExecutablePath );
if ( tmpBundlePath ) free( tmpBundlePath );
return ret;
if ( buffer ) {
free( buffer );
}
if ( tmpExecutablePath ) {
free( tmpExecutablePath );
}
if ( tmpBundlePath ) {
free( tmpBundlePath );
}
return ret;
}
static long
MatchPersonalities( void )
{
/* IONameMatch support not implemented */
return 0;
/* IONameMatch support not implemented */
return 0;
}
//==========================================================================
static long
MatchLibraries( void )
{
TagPtr prop, prop2;
ModulePtr module, module2;
long done;
TagPtr prop, prop2;
ModulePtr module, module2;
long done;
do {
done = 1;
module = gModuleHead;
do {
done = 1;
module = gModuleHead;
while (module != 0)
{
if (module->willLoad == 1)
{
prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);
if (prop != 0)
{
prop = prop->tag;
while (prop != 0)
{
module2 = gModuleHead;
while (module2 != 0)
{
prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);
if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))
{
if (module2->willLoad == 0) module2->willLoad = 1;
break;
}
module2 = module2->nextModule;
}
prop = prop->tagNext;
}
}
module->willLoad = 2;
done = 0;
}
module = module->nextModule;
}
}
while (!done);
while (module != 0)
{
if (module->willLoad == 1)
{
prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);
return 0;
if (prop != 0)
{
prop = prop->tag;
while (prop != 0)
{
module2 = gModuleHead;
while (module2 != 0)
{
prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);
if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))
{
if (module2->willLoad == 0)
{
module2->willLoad = 1;
}
break;
}
module2 = module2->nextModule;
}
prop = prop->tagNext;
}
}
module->willLoad = 2;
done = 0;
}
module = module->nextModule;
}
}
while (!done);
return 0;
}
static ModulePtr
FindModule( char * name )
{
ModulePtr module;
TagPtr prop;
ModulePtr module;
TagPtr prop;
module = gModuleHead;
while (module != 0)
{
prop = GetProperty(module->dict, kPropCFBundleIdentifier);
if ((prop != 0) && !strcmp(name, prop->string)) {
break;
}
module = module->nextModule;
}
module = gModuleHead;
while (module != 0)
{
prop = GetProperty(module->dict, kPropCFBundleIdentifier);
if ((prop != 0) && !strcmp(name, prop->string)) break;
module = module->nextModule;
}
return module;
return module;
}
#endif /* NOTDEF */
TagPtr moduleDict, required;
ModulePtr tmpModule;
pos = 0;
pos = 0;
while (1)
{
length = XMLParseNextTag(buffer + pos, &moduleDict);
if (length == -1) break;
pos += length;
if (moduleDict == 0) continue;
if (moduleDict->type == kTagTypeDict) break;
XMLFreeTag(moduleDict);
}
if (length == -1) return -1;
while (1)
{
length = XMLParseNextTag(buffer + pos, &moduleDict);
if (length == -1) {
break;
}
pos += length;
if (moduleDict == 0) {
continue;
}
if (moduleDict->type == kTagTypeDict) {
break;
}
XMLFreeTag(moduleDict);
}
if (length == -1) {
return -1;
}
required = XMLGetProperty(moduleDict, kPropOSBundleRequired);
if ( (required == 0) || (required->type != kTagTypeString) || !strcmp(required->string, "Safe Boot"))
return -2;
}
tmpModule = malloc(sizeof(Module));
if (tmpModule == 0)
{
XMLFreeTag(moduleDict);
return -1;
}
tmpModule->dict = moduleDict;
tmpModule = malloc(sizeof(Module));
if (tmpModule == 0) {
XMLFreeTag(moduleDict);
return -1;
}
tmpModule->dict = moduleDict;
// For now, load any module that has OSBundleRequired != "Safe Boot".
// For now, load any module that has OSBundleRequired != "Safe Boot".
tmpModule->willLoad = 1;
tmpModule->willLoad = 1;
*module = tmpModule;
*module = tmpModule;
// Get the personalities.
// Get the personalities.
*personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);
*personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);
return 0;
return 0;
}
#if NOTDEF
static char gPlatformName[64];
#endif
long
long
DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
{
long ret;
}
ret = ThinFatFile(&binary, &len);
if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
{
archCpuType=CPU_TYPE_I386;
ret = ThinFatFile(&binary, &len);
}
// Notify modules that the kernel has been decompressed, thinned and is about to be decoded
if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
{
archCpuType=CPU_TYPE_I386;
ret = ThinFatFile(&binary, &len);
}
// Notify modules that the kernel has been decompressed, thinned and is about to be decoded
execute_hook("DecodeKernel", (void*)binary, NULL, NULL, NULL);
ret = DecodeMachO(binary, rentry, raddr, rsize);
if (ret<0 && archCpuType==CPU_TYPE_X86_64)
{
archCpuType=CPU_TYPE_I386;
ret = DecodeMachO(binary, rentry, raddr, rsize);
}
return ret;
ret = DecodeMachO(binary, rentry, raddr, rsize);
if (ret<0 && archCpuType==CPU_TYPE_X86_64)
{
archCpuType=CPU_TYPE_I386;
ret = DecodeMachO(binary, rentry, raddr, rsize);
}
return ret;
}
trunk/i386/boot2/boot.c
7575
7676
7777
78
78
7979
8080
8181
......
9696
9797
9898
99
100
101
102
99
100
101
102
103103
104104
105
105
106106
107107
108108
......
129129
130130
131131
132
132
133133
134134
135
135
136136
137137
138138
139139
140
140
141141
142142
143
143
144144
145145
146
146
147147
148148
149
149
150150
151
151
152152
153153
154154
155
155
156156
157
157
158158
159
159
160160
161161
162162
163163
164164
165
165
166166
167
167
168168
169169
170170
171171
172
172
173173
174
175
174
176175
177176
178177
179178
180
179
181180
182181
183182
184183
185
184
186185
187186
188187
189188
190189
191
190
192191
193
192
194193
195
194
196195
197
196
198197
199
198
200199
201200
202201
......
207206
208207
209208
210
209
211210
212
213
211
214212
215213
216214
217215
218216
219
217
220218
221219
222220
......
225223
226224
227225
228
226
227
229228
230229
231230
232
231
233232
234
235
233
236234
237235
238
236
239237
240238
241239
......
247245
248246
249247
250
248
251249
252250
253251
254
255
256
252
253
254
257255
258
259
256
257
260258
261
262
263
264
265
266
267
268
269
270
271
272
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
273279
274
275
276
277
278
279
280
281
282
283280
284281
285282
......
287284
288285
289286
290
291
292
293
294
295
296
297
298
299
300
301
287
288
289
290
291
292
293
294
295
296
297
298
299
302300
303301
304302
305
306
307
308
303
304
305
306
307
309308
310309
311310
......
373372
374373
375374
376
375
377376
378377
379378
380
379
381380
382381
383
382
384383
385384
386
385
387386
388
387
389388
390389
391390
......
396395
397396
398397
399
398
400399
401400
402
401
403402
404403
405404
406405
407
406
408407
409408
410
409
411410
412411
413412
414
413
415414
416415
417416
418417
419
418
420419
421420
422
421
423422
424423
425
424
426425
427426
428427
429428
430429
431
430
432431
433432
434433
......
436435
437436
438437
439
438
440439
441440
442441
443442
444443
445
444
446445
447446
448447
449448
450449
451450
452
451
453452
454453
455
454
456455
457
456
458457
459458
460
459
461460
462461
463462
......
474473
475474
476475
477
476
478477
479
478
480479
481480
482481
......
486485
487486
488487
489
488
490489
491490
492491
......
494493
495494
496495
497
496
498497
499498
500499
501
500
502501
503502
504503
......
519518
520519
521520
522
521
523522
524
523
525524
526525
527526
......
533532
534533
535534
536
535
537536
538537
539
538
540539
541540
542541
543542
544543
545
544
546545
547546
548547
549548
550549
551
550
552551
553552
554553
555554
556555
557
556
558557
559558
560
559
561560
562561
563562
564563
565564
566565
567
566
568567
569568
570569
571
570
572571
573572
574573
575574
576
575
577576
578577
579578
580579
581580
582
581
583582
584583
585
584
586585
587586
588
587
589588
590589
591590
592
591
593592
594593
595
594
596595
597
596
598597
599598
600
599
601600
602601
603
602
604603
605604
606605
......
618617
619618
620619
621
620
622621
623622
624623
......
639638
640639
641640
642
641
643642
644643
645644
......
680679
681680
682681
683
682
684683
685684
686685
......
689688
690689
691690
692
691
693692
694
693
695694
696695
697696
698697
699
698
700699
701700
702701
703
702
704703
705704
706705
......
775774
776775
777776
778
777
779778
780779
781780
chargRootDevice[ROOT_DEVICE_SIZE];
chargMKextName[512];
chargMacOSVersion[8];
intbvCount = 0, gDeviceCount = 0;
intbvCount = 0, gDeviceCount = 0;
//intmenucount = 0;
longgBootMode; /* defaults to 0 == kBootModeNormal */
BVRefbvr, menuBVR, bvChain;
static void zeroBSS(void)
{
extern char bss_start __asm("section$start$__DATA$__bss");
extern char bss_end __asm("section$end$__DATA$__bss");
extern char common_start __asm("section$start$__DATA$__common");
extern char common_end __asm("section$end$__DATA$__common");
extern char bss_end __asm("section$end$__DATA$__bss");
extern char common_start __asm("section$start$__DATA$__common");
extern char common_end __asm("section$end$__DATA$__common");
bzero(&bss_start, (&bss_end - &bss_start));
bzero(&common_start, (&common_end - &common_start));
}
}
//==========================================================================
// Malloc error function
{
intret;
entry_tkernelEntry;
bootArgs->kaddr = bootArgs->ksize = 0;
execute_hook("ExecKernel", (void*)binary, NULL, NULL, NULL);
ret = DecodeKernel(binary,
&kernelEntry,
(char **) &bootArgs->kaddr,
(int *)&bootArgs->ksize );
if ( ret != 0 )
return ret;
// Reserve space for boot args
reserveKernBootStruct();
// Notify modules that the kernel has been decoded
execute_hook("DecodedKernel", (void*)binary, (void*)bootArgs->kaddr, (void*)bootArgs->ksize, NULL);
setupFakeEfi();
// Load boot drivers from the specifed root path.
//if (!gHaveKernelCache)
LoadDrivers("/");
execute_hook("DriversLoaded", (void*)binary, NULL, NULL, NULL);
clearActivityIndicator();
if (gErrors) {
printf("Errors encountered while starting up the computer.\n");
printf("Pausing %d seconds...\n", kBootErrorTimeout);
sleep(kBootErrorTimeout);
}
md0Ramdisk();
verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64");
verbose("Boot Args: %s\n", bootArgs->CommandLine);
// Cleanup the PXE base code.
if ( (gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit ) {
if ( (ret = nbpUnloadBaseCode()) != nbpStatusSuccess )
{
if ( (ret = nbpUnloadBaseCode()) != nbpStatusSuccess ) {
printf("nbpUnloadBaseCode error %d\n", (int) ret);
sleep(2);
}
}
bool dummyVal;
if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->chameleonConfig) && dummyVal) {
showTextBuffer(msgbuf, strlen(msgbuf));
}
usb_loop();
// If we were in text mode, switch to graphics mode.
// This will draw the boot graphics unless we are in
// verbose mode.
if (gVerboseMode)
if (gVerboseMode) {
setVideoMode( GRAPHICS_MODE, 0 );
else
} else {
drawBootGraphics();
}
setupBooterLog();
finalizeBootStruct();
// Jump to kernel's entry point. There's no going back now.
if ((checkOSVersion("10.7")) || (checkOSVersion("10.8")) || (checkOSVersion("10.9")))
{
// Masking out so that Lion doesn't doublefault
outb(0x21, 0xff);/* Maskout all interrupts Pic1 */
outb(0xa1, 0xff);/* Maskout all interrupts Pic2 */
startprog( kernelEntry, bootArgs );
}
else {
} else {
// Notify modules that the kernel is about to be started
execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgsPreLion, NULL, NULL);
startprog( kernelEntry, bootArgsPreLion );
}
// Not reached
return 0;
}
//==========================================================================
// LoadKernelCache - Try to load Kernel Cache.
// return the length of the loaded cache file or -1 on error
long LoadKernelCache(const char* cacheFile, void **binary) {
long LoadKernelCache(const char* cacheFile, void **binary)
{
charkernelCacheFile[512];
charkernelCachePath[512];
longflags, time, cachetime, kerneltime, exttime, ret=-1;
unsigned long adler32;
unsigned long adler32;
if((gBootMode & kBootModeSafe) != 0)
{
if((gBootMode & kBootModeSafe) != 0) {
verbose("Kernel Cache ignored.\n");
return -1;
}
}
// Use specify kernel cache file if not empty
if (cacheFile[0] != 0)
// Lion, Mountain Lion and Mavericks prelink kernel cache file
if ((checkOSVersion("10.7")) || (checkOSVersion("10.8")) || (checkOSVersion("10.9")))
{
snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCachePathSnow);
snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCachePathSnow);
}
// Snow Leopard prelink kernel cache file
else if (checkOSVersion("10.6")) {
snprintf(kernelCacheFile, sizeof(kernelCacheFile), "kernelcache_%s",
(archCpuType == CPU_TYPE_I386) ? "i386" : "x86_64");
int lnam = strlen(kernelCacheFile) + 9; //with adler32
snprintf(kernelCacheFile, sizeof(kernelCacheFile), "kernelcache_%s",
(archCpuType == CPU_TYPE_I386) ? "i386" : "x86_64");
int lnam = strlen(kernelCacheFile) + 9; //with adler32
char* name;
long prev_time = 0;
char* name;
long prev_time = 0;
struct dirstuff* cacheDir = opendir(kDefaultCachePathSnow);
/* TODO: handle error? */
if (cacheDir) {
while (readdir(cacheDir, (const char**)&name, &flags, &time) >= 0) {
if (((flags & kFileTypeMask) != kFileTypeDirectory) && time > prev_time
&& strstr(name, kernelCacheFile) && (name[lnam] != '.')) {
snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%s%s", kDefaultCachePathSnow, name);
prev_time = time;
}
}
}
closedir(cacheDir);
struct dirstuff* cacheDir = opendir(kDefaultCachePathSnow);
/* TODO: handle error? */
if (cacheDir) {
while(readdir(cacheDir, (const char**)&name, &flags, &time) >= 0) {
if (((flags & kFileTypeMask) != kFileTypeDirectory) && time > prev_time
&& strstr(name, kernelCacheFile) && (name[lnam] != '.')) {
snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%s%s", kDefaultCachePathSnow, name);
prev_time = time;
}
}
}
closedir(cacheDir);
} else {
// Reset cache name.
bzero(gCacheNameAdler + 64, sizeof(gCacheNameAdler) - 64);
snprintf(gCacheNameAdler + 64, sizeof(gCacheNameAdler) - 64,
"%s,%s",
gRootDevice, bootInfo->bootFile);
adler32 = Adler32((unsigned char *)gCacheNameAdler, sizeof(gCacheNameAdler));
snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%s.%08lX", kDefaultCachePathLeo, adler32);
}
else {
// Reset cache name.
bzero(gCacheNameAdler + 64, sizeof(gCacheNameAdler) - 64);
snprintf(gCacheNameAdler + 64, sizeof(gCacheNameAdler) - 64,
"%s,%s",
gRootDevice, bootInfo->bootFile);
adler32 = Adler32((unsigned char *)gCacheNameAdler, sizeof(gCacheNameAdler));
snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%s.%08lX", kDefaultCachePathLeo, adler32);
}
}
// Check if the kernel cache file exists
// If boot from a boot helper partition check the kernel cache file on it
if (gBootVolume->flags & kBVFlagBooter) {
snprintf(kernelCachePath, sizeof(kernelCachePath), "com.apple.boot.P%s", kernelCacheFile);
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
snprintf(kernelCachePath, sizeof(kernelCachePath), "com.apple.boot.R%s", kernelCacheFile);
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
snprintf(kernelCachePath, sizeof(kernelCachePath), "com.apple.boot.S%s", kernelCacheFile);
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((flags & kFileTypeMask) != kFileTypeFlat)
ret = -1;
}
}
snprintf(kernelCachePath, sizeof(kernelCachePath), "com.apple.boot.P%s", kernelCacheFile);
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
snprintf(kernelCachePath, sizeof(kernelCachePath), "com.apple.boot.R%s", kernelCacheFile);
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
snprintf(kernelCachePath, sizeof(kernelCachePath), "com.apple.boot.S%s", kernelCacheFile);
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((flags & kFileTypeMask) != kFileTypeFlat) {
ret = -1;
}
}
}
}
// If not found, use the original kernel cache path.
if (ret == -1) {
strlcpy(kernelCachePath, kernelCacheFile, sizeof(kernelCachePath));
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((flags & kFileTypeMask) != kFileTypeFlat)
ret = -1;
strlcpy(kernelCachePath, kernelCacheFile, sizeof(kernelCachePath));
ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime);
if ((flags & kFileTypeMask) != kFileTypeFlat) {
ret = -1;
}
}
// Exit if kernel cache file wasn't found
intstatus;
unsigned intallowBVFlags = kBVFlagSystemVolume | kBVFlagForeignBoot;
unsigned intdenyBVFlags = kBVFlagEFISystem;
// Set reminder to unload the PXE base code. Neglect to unload
// the base code will result in a hang or kernel panic.
gUnloadPXEOnExit = true;
// Record the device that the booter was loaded from.
gBIOSDev = biosdev & kBIOSDevMask;
// Initialize boot info structure.
initKernBootStruct();
initBooterLog();
// Setup VGA text mode.
// Not sure if it is safe to call setVideoMode() before the
// config table has been loaded. Call video_mode() instead.
#if DEBUG
printf("after video_mode\n");
#endif
// Scan and record the system's hardware information.
scan_platform();
// First get info for boot volume.
scanBootVolumes(gBIOSDev, 0);
bvChain = getBVChainForBIOSDev(gBIOSDev);
setBootGlobals(bvChain);
// Load boot.plist config file
status = loadChameleonConfig(&bootInfo->chameleonConfig);
if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->chameleonConfig) && quiet) {
gBootMode |= kBootModeQuiet;
}
// Override firstRun to get to the boot menu instantly by setting "Instant Menu"=y in system config
if (getBoolForKey(kInstantMenuKey, &instantMenu, &bootInfo->chameleonConfig) && instantMenu) {
firstRun = false;
}
// Loading preboot ramdisk if exists.
loadPrebootRAMDisk();
// Disable rescan option by default
gEnableCDROMRescan = false;
// Enable it with Rescan=y in system config
if (getBoolForKey(kRescanKey, &gEnableCDROMRescan, &bootInfo->chameleonConfig)
&& gEnableCDROMRescan) {
gEnableCDROMRescan = true;
}
// Ask the user for Rescan option by setting "Rescan Prompt"=y in system config.
rescanPrompt = false;
if (getBoolForKey(kRescanPromptKey, &rescanPrompt , &bootInfo->chameleonConfig)
{
gEnableCDROMRescan = promptForRescanOption();
}
// Enable touching a single BIOS device only if "Scan Single Drive"=y is set in system config.
if (getBoolForKey(kScanSingleDriveKey, &gScanSingleDrive, &bootInfo->chameleonConfig)
&& gScanSingleDrive) {
gScanSingleDrive = true;
}
// Create a list of partitions on device(s).
if (gScanSingleDrive) {
scanBootVolumes(gBIOSDev, &bvCount);
} else {
scanDisks(gBIOSDev, &bvCount);
}
// Create a separated bvr chain using the specified filters.
bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
gBootVolume = selectBootVolume(bvChain);
// Intialize module system
init_module_system();
#if DEBUG
printf(" Default: %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n",
gBootVolume, gBootVolume->biosdev, gBootVolume->part_no, gBootVolume->flags);
// initGUI() returned with an error, disabling GUI.
useGUI = false;
}
setBootGlobals(bvChain);
// Parse args, load and start kernel.
while (1)
{
intlen, ret = -1;
longflags, sleeptime, time;
void*binary = (void *)kLoadAddr;
char bootFile[sizeof(bootInfo->bootFile)];
charbootFilePath[512];
charkernelCacheFile[512];
// Initialize globals.
sysConfigValid = false;
gErrors = false;
status = getBootOptions(firstRun);
firstRun = false;
if (status == -1) continue;
status = processBootOptions();
// Status == 1 means to chainboot
if ( status ==1 ) break;
}
continue;
}
// Other status (e.g. 0) means that we should proceed with boot.
// Turn off any GUI elements
if ( bootArgs->Video.v_display == GRAPHICS_MODE )
{
drawBackground();
updateVRAM();
}
// Find out which version mac os we're booting.
getOSVersion();
if (platformCPUFeature(CPU_FEATURE_EM64T)) {
archCpuType = CPU_TYPE_X86_64;
} else {
archCpuType = CPU_TYPE_I386;
}
if (getValueForKey(karch, &val, &len, &bootInfo->chameleonConfig)) {
if (strncmp(val, "i386", 4) == 0) {
archCpuType = CPU_TYPE_I386;
}
}
if (getValueForKey(kKernelArchKey, &val, &len, &bootInfo->chameleonConfig)) {
if (strncmp(val, "i386", 4) == 0) {
archCpuType = CPU_TYPE_I386;
}
}
// Notify modules that we are attempting to boot
execute_hook("PreBoot", NULL, NULL, NULL, NULL);
if (!getBoolForKey (kWake, &tryresume, &bootInfo->chameleonConfig)) {
tryresume = true;
tryresumedefault = true;
} else {
tryresumedefault = false;
}
if (!getBoolForKey (kForceWake, &forceresume, &bootInfo->chameleonConfig)) {
forceresume = false;
}
if (forceresume) {
tryresume = true;
tryresumedefault = false;
}
while (tryresume) {
const char *tmp;
BVRef bvr;
if (!getValueForKey(kWakeImage, &val, &len, &bootInfo->chameleonConfig))
val = "/private/var/vm/sleepimage";
// Do this first to be sure that root volume is mounted
ret = GetFileInfo(0, val, &flags, &sleeptime);
if ((bvr = getBootVolumeRef(val, &tmp)) == NULL)
break;
// Can't check if it was hibernation Wake=y is required
if (bvr->modTime == 0 && tryresumedefault)
break;
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat))
break;
if (!forceresume && ((sleeptime+3)<bvr->modTime)) {
#if DEBUG
#if DEBUG
printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n",
bvr->modTime-sleeptime);
#endif
#endif
break;
}
HibernateBoot((char *)val);
break;
}
val++;
}
/* FIXME: check len vs sizeof(kernelCacheFile) */
strlcpy(kernelCacheFile, val, len + 1);
strlcpy(kernelCacheFile, val, len + 1);
} else {
kernelCacheFile[0] = 0; // Use default kernel cache file
}
useKernelCache = false;
} while(0);
do {
if (useKernelCache) {
ret = LoadKernelCache(kernelCacheFile, &binary);
// No alternate location found, using the original kernel image path.
strlcpy(bootFilePath, bootFile, sizeof(bootFilePath));
}
verbose("Loading kernel %s\n", bootFilePath);
ret = LoadThinFatFile(bootFilePath, &binary);
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
ret = LoadThinFatFile(bootFilePath, &binary);
}
} while (0);
clearActivityIndicator();
#if DEBUG
printf("Pausing...");
sleep(8);
#endif
if (ret <= 0) {
printf("Can't find %s\n", bootFile);
sleep(1);
if (gBootFileType == kNetworkDeviceType) {
// Return control back to PXE. Don't unload PXE base code.
gUnloadPXEOnExit = false;
unsigned long s2 = 0; // (adler >> 16) & 0xffff;
unsigned long result;
int k;
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
trunk/i386/boot2/boot2.s
6464
6565
6666
67
67
6868
6969
7070
#
# Returns:
#
LABEL(boot2)
LABEL(boot2) # Entry point at 0:BOOTER_ADDR (will be called by boot1)
pushl %ecx # Save general purpose registers
pushl %ebx
pushl %ebp
trunk/i386/boot2/boot.h
193193
194194
195195
196
197
198
199
196
197
198
199
200200
201201
202202
......
215215
216216
217217
218
219
220
221
222
223
224
225
226
227
218
219
220
221
222
223
224
225
226
227
228
229
230
231
228232
229233
230234
......
265269
266270
267271
268
269
272
273
270274
271275
272276
......
275279
276280
277281
278
279
280
281
282
283
284
285
286
282
283
284
285
286
287
288
289
290
287291
288292
289293
* Boot Modes
*/
enum {
kBootModeNormal = 0,
kBootModeSafe = 1,
kBootModeSecure = 2,
kBootModeQuiet = 4
kBootModeNormal = 0,
kBootModeSafe = 1,
kBootModeSecure = 2,
kBootModeQuiet = 4
};
extern void initialize_runtime();
extern int getVideoMode();
extern void spinActivityIndicator();
extern void clearActivityIndicator();
extern void drawColorRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
unsigned char colorIndex );
extern void drawDataRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
unsigned char * data );
extern void drawColorRectangle(
unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
unsigned char colorIndex
);
extern void drawDataRectangle(
unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
unsigned char * data
);
extern int
convertImage( unsigned short width,
unsigned short height,
char *getMemoryInfoString();
typedef struct {
char name[80];
void * param;
char name[80];
void * param;
} MenuItem;
/*
extern int decompress_lzss(u_int8_t *dst, u_int8_t *src, u_int32_t srclen);
struct compressed_kernel_header {
u_int32_t signature;
u_int32_t compress_type;
u_int32_t adler32;
u_int32_t uncompressed_size;
u_int32_t compressed_size;
u_int32_t reserved[11];
char platform_name[64];
char root_path[256];
u_int8_t data[0];
u_int32_t signature;
u_int32_t compress_type;
u_int32_t adler32;
u_int32_t uncompressed_size;
u_int32_t compressed_size;
u_int32_t reserved[11];
char platform_name[64];
char root_path[256];
u_int8_t data[0];
};
typedef struct compressed_kernel_header compressed_kernel_header;
trunk/i386/boot2/modules.c
107107
108108
109109
110
111
110
112111
113112
114113
115
116
114
117115
118116
119117
......
123121
124122
125123
126
124
127125
128126
129127
......
985983
986984
987985
988
989
990
991
992
993
994
995
986
987
988
989
990
991
992
993
996994
997995
998996
struct dirstuff* moduleDir = opendir("/Extra/modules/");
while (readdir(moduleDir, (const char**)&name, &flags, &time) >= 0)
{
if (strcmp(&name[strlen(name) - sizeof("dylib")], ".dylib") == 0)
{
if(strcmp(&name[strlen(name) - sizeof("dylib")], ".dylib") == 0) {
char* tmp = malloc(strlen(name) + 1);
strcpy(tmp, name);
if (!load_module(tmp))
{
if(!load_module(tmp)) {
// failed to load
// free(tmp);
}
DBG("Ignoring %s\n", name);
}
}
closedir(moduleDir);
closedir(moduleDir);
}
UInt32 addr = lookup_all_symbols(symbol);
if(addr != 0xFFFFFFFF)
{
//DBG("Replacing %s to point to 0x%x\n", symbol, newAddress);
UInt32* jumpPointer = malloc(sizeof(UInt32*));
char* binary = (char*)addr;
*binary++ = 0xFF;// Jump
*binary++ = 0x25;// Long Jump
*((UInt32*)binary) = (UInt32)jumpPointer;
*jumpPointer = (UInt32)newAddress;
return 1;
//DBG("Replacing %s to point to 0x%x\n", symbol, newAddress);
UInt32* jumpPointer = malloc(sizeof(UInt32*));
char* binary = (char*)addr;
*binary++ = 0xFF;// Jump
*binary++ = 0x25;// Long Jump
*((UInt32*)binary) = (UInt32)jumpPointer;
*jumpPointer = (UInt32)newAddress;
return 1;
}
return 0;
}
trunk/i386/boot2/gui.c
18111811
18121812
18131813
1814
1814
18151815
18161816
18171817
currentline = lines - visiblelines;
}
}
free(text);
free(text);
}
void animateProgressBar()
trunk/i386/boot2/ramdisk.c
2929
3030
3131
32
32
3333
3434
3535
3636
37
37
3838
3939
4040
4141
42
42
4343
4444
4545
......
151151
152152
153153
154
154
155155
156156
157157
&bootInfo->chameleonConfig))
{
// Use user specified md0 file
snprintf(filename, sizeof(filename), "%s", override_filename);
snprintf(filename, sizeof(filename), "%s", override_filename);
fh = open(filename, 0);
if(fh < 0)
{
snprintf(filename, sizeof(filename), "rd(0,0)/Extra/%s", override_filename);
snprintf(filename, sizeof(filename), "rd(0,0)/Extra/%s", override_filename);
fh = open(filename, 0);
if(fh < 0)
{
snprintf(filename, sizeof(filename), "/Extra/%s", override_filename);
snprintf(filename, sizeof(filename), "/Extra/%s", override_filename);
fh = open(filename, 0);
}
}
if (error == 0)
{
// Save filename in gRAMDiskFile to display information.
strlcpy(gRAMDiskFile, param, sizeof(gRAMDiskFile));
strlcpy(gRAMDiskFile, param, sizeof(gRAMDiskFile));
// Set gMI as well for the multiboot ramdisk driver hook.
gMI = gRAMDiskMI = malloc(sizeof(multiboot_info));
trunk/i386/boot2/options.c
641641
642642
643643
644
645
646
647
648
649
650
651
644
645
646
647
648
649
652650
653
654
655
656
651
652
653
654
655
656
657
657658
658659
659
660
660661
661662
662663
663
664
665
664
665
666
666667
667668
668669
char *getMemoryInfoString()
{
int i, bufflen;
MemoryRange *mp = bootInfo->memoryMap;
char *buff = malloc(sizeof(char)*1024);
if (!buff)
return 0;
static const char info[] = "BIOS reported memory ranges:\n";
bufflen = sprintf(buff, "%s", info);
int i, bufflen;
MemoryRange *mp = bootInfo->memoryMap;
char *buff = malloc(sizeof(char)*1024);
if(!buff) {
return 0;
}
for (i = 0;
(i < bootInfo->memoryMapCount) && (bufflen < 1024); /* prevent buffer overflow */
i++) {
bufflen += snprintf(buff+bufflen, 1024-bufflen, "Base 0x%08x%08x, ",
static const char info[] = "BIOS reported memory ranges:\n";
bufflen = sprintf(buff, "%s", info);
for (i = 0;
(i < bootInfo->memoryMapCount) && (bufflen < 1024); /* prevent buffer overflow */
i++) {
bufflen += snprintf(buff+bufflen, 1024-bufflen, "Base 0x%08x%08x, ",
(unsigned long)(mp->base >> 32),
(unsigned long)(mp->base));
bufflen += snprintf(buff+bufflen, 1024-bufflen, "length 0x%08x%08x, type %d\n",
bufflen += snprintf(buff+bufflen, 1024-bufflen, "length 0x%08x%08x, type %d\n",
(unsigned long)(mp->length >> 32),
(unsigned long)(mp->length),
mp->type);
mp++;
}
return buff;
mp++;
}
return buff;
}
//==========================================================================
trunk/i386/config/symbol.c
881881
882882
883883
884
885
886
887
888
889
890
884
885
886
887
888
889
890
891891
892892
893893
newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
if (newlen > reslen) {
char* newres = NULL;
if (!(newres = realloc(res, newlen))) {
/* TODO: handle error gracefully - for now, punt */
break;
}
res = newres;
reslen = newlen;
char* newres = NULL;
if (!(newres = realloc(res, newlen))) {
/* TODO: handle error gracefully - for now, punt */
break;
}
res = newres;
reslen = newlen;
}
strcat(res, symval);
trunk/i386/config/confdata.c
902902
903903
904904
905
905
906906
907907
908908
}
fclose(out);
fclose(out_h);
fclose(out_inc);
fclose(out_inc);
name = getenv("CCONFIG_AUTOHEADER");
if (!name) name = "autoconf.h";
trunk/i386/libsa/printf.c
6565
6666
6767
68
69
68
69
7070
71
72
73
74
75
76
77
71
72
73
74
75
76
77
7878
7979
8080
/*VARARGS1*/
int snprintf(char * str, size_t size, const char * fmt, ...)
{
va_list ap;
struct putc_info pi;
va_list ap;
struct putc_info pi;
va_start(ap, fmt);
pi.str = str;
pi.last_str = str + size - 1;
prf(fmt, ap, sputc, &pi);
*pi.str = '\0';
va_end(ap);
return (pi.str - str);
va_start(ap, fmt);
pi.str = str;
pi.last_str = str + size - 1;
prf(fmt, ap, sputc, &pi);
*pi.str = '\0';
va_end(ap);
return (pi.str - str);
}
/*VARARGS1*/
trunk/i386/libsa/string.c
161161
162162
163163
164
165
166
167
164
165
166
167
168
168169
169170
170171
......
278279
279280
280281
281
282
282283
283284
284285
......
290291
291292
292293
293
294
294295
295
296
296297
297298
298
299
299300
300301
301302
{
register char *ret = s1;
while (n && (*s1++ = *s2++))
--n;
/* while (n--) *s1++ = '\0'; */
if (n > 0)
bzero(s1, n);
--n;
/* while (n--) *s1++ = '\0'; */
if (n > 0) {
bzero(s1, n);
}
return ret;
}
if (*start == '"')
{
start++;
end = strchr(start, '"');
if(end)
quoted = true;
for ( end = start; *end && !isspace(*end); end++ )
{}
}
*len = end - start;
if(next)
*next = quoted ? end+1 : end;
return start;
}

Archive Download the corresponding diff file

Revision: 2327