Chameleon

Chameleon Commit Details

Date:2014-01-09 13:10:23 (5 years 10 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);
// det