Chameleon

Chameleon Commit Details

Date:2011-08-01 05:13:00 (12 years 9 months ago)
Author:Azimutz
Commit:1251
Parents: 1250
Message:Sync with trunk (r1248).
Changes:
C/trunk/i386/boot0/boot0hfs.s → /branches/azimutz/trunkAutoResolution/i386/boot0/boot0hfs.s
C/trunk/package/Resources/Russian.lproj → /branches/azimutz/trunkAutoResolution/package/Resources/Russian.lproj
C/trunk/i386/boot0/boot0md.s → /branches/azimutz/trunkAutoResolution/i386/boot0/boot0md.s
M/branches/azimutz/trunkAutoResolution/i386/libsaio/cpu.h
M/branches/azimutz/trunkAutoResolution/i386/boot0/Makefile
M/branches/azimutz/trunkAutoResolution/CREDITS
M/branches/azimutz/trunkAutoResolution/doc/BootHelp.txt
M/branches/azimutz/trunkAutoResolution
M/branches/azimutz/trunkAutoResolution/i386/boot0/boot0.s
M/branches/azimutz/trunkAutoResolution/i386/boot2/boot.c
M/branches/azimutz/trunkAutoResolution/BLOCKERS
M/branches/azimutz/trunkAutoResolution/package/buildpkg.sh
M/branches/azimutz/trunkAutoResolution/i386/libsaio/nvidia.c
M/branches/azimutz/trunkAutoResolution/i386/boot2/boot.h
M/branches/azimutz/trunkAutoResolution/CHANGES
M/branches/azimutz/trunkAutoResolution/i386/libsaio/ati.c
M/branches/azimutz/trunkAutoResolution/i386/libsaio/stringTable.c
M/branches/azimutz/trunkAutoResolution/i386/boot2/drivers.c
M/branches/azimutz/trunkAutoResolution/Makefile
M/branches/azimutz/trunkAutoResolution/i386/libsaio/acpi_patcher.c
M/branches/azimutz/trunkAutoResolution/i386/libsaio/cpu.c
M/branches/azimutz/trunkAutoResolution/i386/boot0/Cconfig
M/branches/azimutz/trunkAutoResolution/i386/libsaio/platform.h

File differences

branches/azimutz/trunkAutoResolution/i386/libsaio/acpi_patcher.c
152152
153153
154154
155
155156
156157
157158
......
184185
185186
186187
188
189
190
187191
188192
189193
......
204208
205209
206210
207
211
208212
209213
210
211
214
215
212216
217
218
219
220
221
222
223
213224
214225
215226
......
236247
237248
238249
250
239251
240
241
242
252
253
254
255
243256
244257
245258
......
254267
255268
256269
257
258
259
260
261
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
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
262323
263
264
265
266
267
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
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
295366
296367
297368
uint8_tacpi_cpu_count = 0;
char* acpi_cpu_name[32];
uint32_t acpi_cpu_p_blk = 0;
void get_acpi_cpu_names(unsigned char* dsdt, uint32_t length)
{
acpi_cpu_name[acpi_cpu_count] = malloc(4);
memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4);
i = offset + 5;
if (acpi_cpu_count == 0)
acpi_cpu_p_blk = dsdt[i] | (dsdt[i+1] << 8);
verbose("Found ACPI CPU: %c%c%c%c\n", acpi_cpu_name[acpi_cpu_count][0], acpi_cpu_name[acpi_cpu_count][1], acpi_cpu_name[acpi_cpu_count][2], acpi_cpu_name[acpi_cpu_count][3]);
0x31, 0x03, 0x10, 0x20 /* 1.._*/
};
char cstate_resource_template[] =
char resource_template_register_fixedhw[] =
{
0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F,
0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x79, 0x00
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x79, 0x00
};
char resource_template_register_systemio[] =
{
0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x01,
0x08, 0x00, 0x00, 0x15, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x79, 0x00,
};
if (Platform.CPU.Vendor != 0x756E6547) {
verbose ("Not an Intel platform: C-States will not be generated !!!\n");
bool c2_enabled = false;
bool c3_enabled = false;
bool c4_enabled = false;
bool cst_using_sustemio = false;
getBoolForKey(kEnableC2States, &c2_enabled, &bootInfo->chameleonConfig);
getBoolForKey(kEnableC3States, &c3_enabled, &bootInfo->chameleonConfig);
getBoolForKey(kEnableC4States, &c4_enabled, &bootInfo->chameleonConfig);
getBoolForKey(kEnableC2State, &c2_enabled, &bootInfo->chameleonConfig);
getBoolForKey(kEnableC3State, &c3_enabled, &bootInfo->chameleonConfig);
getBoolForKey(kEnableC4State, &c4_enabled, &bootInfo->chameleonConfig);
getBoolForKey(kCSTUsingSystemIO, &cst_using_sustemio, &bootInfo->chameleonConfig);
c2_enabled = c2_enabled | (fadt->C2_Latency < 100);
c3_enabled = c3_enabled | (fadt->C3_Latency < 1000);
aml_add_byte(pack, cstates_count);
struct aml_chunk* tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x00; // C1
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x01); // C1
aml_add_byte(tmpl, 0x01); // Latency
aml_add_word(tmpl, 0x03e8); // Power
if (cst_using_sustemio)
{
// C1
resource_template_register_fixedhw[8] = 0x00;
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
uint8_t p_blk_lo, p_blk_hi;
if (c2_enabled) // C2
{
p_blk_lo = acpi_cpu_p_blk + 4;
p_blk_hi = (acpi_cpu_p_blk + 4) >> 8;
tmpl = aml_add_package(pack);
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
}
if (c4_enabled) // C4
{
p_blk_lo = acpi_cpu_p_blk + 5;
p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
tmpl = aml_add_package(pack);
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
}
else if (c3_enabled) // C3
{
p_blk_lo = acpi_cpu_p_blk + 5;
p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
tmpl = aml_add_package(pack);
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_dword(tmpl, 0x0000015e); // Power
}
// C2
if (c2_enabled)
{
tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x10; // C2
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x02); // C2
aml_add_byte(tmpl, fadt->C2_Latency);
aml_add_word(tmpl, 0x01f4); // Power
}
// C4
if (c4_enabled)
{
tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x30; // C4
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x04); // C4
aml_add_word(tmpl, fadt->C3_Latency / 2); // TODO: right latency for C4
aml_add_byte(tmpl, 0xfa); // Power
}
else
// C3
if (c3_enabled)
{
tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x20; // C3
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x03); // C3
aml_add_word(tmpl, fadt->C3_Latency);
aml_add_word(tmpl, 0x015e); // Power
}
}
else
{
// 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_dword(tmpl, 0x000003e8); // Power
resource_template_register_fixedhw[18] = 0x03;
if (c2_enabled) // C2
{
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_dword(tmpl, 0x000001f4); // Power
}
if (c4_enabled) // C4
{
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_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_dword(tmpl, 0x0000015e); // Power
}
}
// Aliaces
int i;
branches/azimutz/trunkAutoResolution/i386/libsaio/nvidia.c
11
2
2
33
4
4
55
6
7
8
9
6
7
8
9
1010
11
12
13
14
11
12
13
14
1515
16
17
16
17
1818
1919
2020
2121
22
23
22
23
2424
2525
2626
......
4848
4949
5050
51
5251
5352
5453
......
6665
6766
6867
69
70
71
72
73
68
69
70
71
72
73
7474
75
76
77
78
7975
8076
81
82
83
84
85
86
87
88
89
77
78
79
80
81
82
83
84
9085
9186
9287
......
10499
105100
106101
102
103
104
105
107106
108107
109108
......
831830
832831
833832
833
834834
835835
836
836837
837838
838839
......
842843
843844
844845
845
846
846847
847848
848849
......
850851
851852
852853
854
853855
854856
855857
856858
859
857860
858861
859862
......
866869
867870
868871
869
872
873
870874
871875
872
873
874
875
876
877
878
879
880
876881
877
878
879
882
883
884
880885
881
886
887
882888
883889
884
890
891
885892
886
893
887894
895
888896
889
897
898
899
890900
891901
892902
893
894
895
903
904
905
906
896907
897908
898
909
910
911
899912
900913
901914
902915
903
916
917
918
904919
905920
906921
907
922
923
924
908925
909926
910927
911928
912
929
913930
914931
915
916
932
933
934
935
917936
918937
919938
920939
921940
922
941
942
923943
924944
945
925946
926947
927948
......
933954
934955
935956
936
937957
938958
939959
940960
941961
942
943
962
963
964
965
944966
945967
946968
947969
948970
949971
972
950973
951
952
953
974
975
976
977
978
954979
980
955981
956982
957983
958
959
984
985
986
960987
961988
962
963
964
989
990
991
992
993
965994
966995
967996
968997
969
970
998
999
1000
1001
9711002
9721003
9731004
9741005
975
1006
1007
1008
9761009
9771010
9781011
9791012
980
1013
1014
9811015
9821016
9831017
9841018
9851019
1020
9861021
9871022
9881023
9891024
990
1025
1026
1027
9911028
9921029
9931030
9941031
995
1032
1033
9961034
9971035
9981036
9991037
10001038
1001
10021039
10031040
10041041
......
10091046
10101047
10111048
1012
1013
1049
1050
1051
1052
1053
10141054
1015
1055
1056
10161057
1058
10171059
10181060
1061
10191062
1020
1063
1064
10211065
10221066
10231067
......
10271071
10281072
10291073
1030
1031
1074
1075
1076
1077
10321078
1079
10331080
1081
10341082
1083
10351084
1036
10371085
10381086
10391087
1040
1041
1042
1043
1044
1088
1089
1090
1091
1092
1093
1094
10451095
10461096
10471097
......
10501100
10511101
10521102
1053
1054
1055
1056
1103
1104
1105
1106
1107
10571108
10581109
1110
10591111
1060
1061
1112
1113
1114
1115
1116
10621117
10631118
10641119
10651120
1121
10661122
10671123
10681124
10691125
10701126
1071
1072
1073
1127
1128
1129
10741130
1075
1076
1131
1132
10771133
1078
1134
10791135
1080
1136
10811137
1082
1138
10831139
1084
1140
10851141
1086
1142
10871143
1088
1144
10891145
1146
10901147
10911148
10921149
10931150
10941151
1095
1152
10961153
10971154
10981155
10991156
11001157
11011158
1102
1159
11031160
11041161
11051162
......
11091166
11101167
11111168
1112
1169
1170
1171
11131172
11141173
11151174
......
11251184
11261185
11271186
1128
1187
1188
11291189
11301190
11311191
1132
1192
1193
11331194
11341195
11351196
11361197
1137
1198
1199
11381200
11391201
11401202
1141
1203
11421204
11431205
11441206
11451207
11461208
1147
1209
11481210
11491211
11501212
......
11531215
11541216
11551217
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
11771238
11781239
11791240
11801241
11811242
11821243
1183
1244
11841245
11851246
11861247
11871248
1188
1249
11891250
11901251
11911252
1192
1253
11931254
1194
1195
1255
1256
1257
1258
1259
11961260
11971261
1198
1262
1263
1264
11991265
12001266
1201
1267
1268
1269
12021270
12031271
12041272
1205
1273
1274
1275
12061276
12071277
1208
1278
12091279
1210
1280
12111281
12121282
12131283
12141284
12151285
1216
1286
1287
12171288
12181289
12191290
1220
1291
12211292
12221293
12231294
12241295
1225
1226
1296
1297
12271298
1228
1299
1300
12291301
12301302
12311303
12321304
1233
1305
1306
12341307
12351308
1236
1309
1310
1311
12371312
12381313
1239
1314
1315
1316
12401317
12411318
1242
1319
1320
1321
12431322
12441323
12451324
1246
1325
12471326
12481327
12491328
12501329
1251
1330
12521331
1253
1332
12541333
1255
1256
1334
1335
1336
1337
12571338
12581339
1259
1340
1341
1342
12601343
12611344
12621345
1263
1346
12641347
12651348
12661349
12671350
1268
1351
12691352
12701353
12711354
1272
1273
1355
1356
12741357
12751358
12761359
......
12781361
12791362
12801363
1364
12811365
1366
12821367
12831368
1369
12841370
1285
1286
1371
1372
1373
1374
12871375
12881376
1289
1290
1291
1377
1378
1379
1380
1381
1382
12921383
1293
1384
1385
12941386
12951387
12961388
1297
1389
1390
12981391
12991392
13001393
......
13081401
13091402
13101403
1311
13121404
1313
1314
1315
1316
1405
1406
1407
1408
1409
1410
1411
13171412
13181413
13191414
13201415
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
13651452
13661453
13671454
......
13691456
13701457
13711458
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
13821470
13831471
1384
1472
13851473
13861474
13871475
1388
1476
13891477
13901478
/*
* NVidia injector
*NVidia injector
*
* Copyright (C) 2009 Jasmin Fazlic, iNDi
*Copyright (C) 2009Jasmin Fazlic, iNDi
*
* NVidia injector is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*NVidia injector is free software: you can redistribute it and/or modify
*it under the terms of the GNU General Public License as published by
*the Free Software Foundation, either version 3 of the License, or
*(at your option) any later version.
*
* NVidia driver and injector is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*NVidia driver and injector is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NVidia injector. If not, see <http://www.gnu.org/licenses/>.
*You should have received a copy of the GNU General Public License
*along with NVidia injector. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Alternatively you can choose to comply with APSL
*/
/*
* DCB-Table parsing is based on software (nouveau driver) originally distributed under following license:
*
* SOFTWARE.
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "pci.h"
#define DBG(x...)
#endif
#define NVIDIA_ROM_SIZE 0x10000
#define PATCH_ROM_SUCCESS 1
#define PATCH_ROM_SUCCESS_HAS_LVDS 2
#define PATCH_ROM_FAILED 0
#define MAX_NUM_DCB_ENTRIES 16
#define NVIDIA_ROM_SIZE0x10000
#define PATCH_ROM_SUCCESS1
#define PATCH_ROM_SUCCESS_HAS_LVDS2
#define PATCH_ROM_FAILED0
#define MAX_NUM_DCB_ENTRIES16
#define TYPE_GROUPED0xff
#define TYPE_GROUPED 0xff
extern uint32_t devices_number;
const char *nvidia_compatible_0[]={ "@0,compatible","NVDA,NVMac" };
const char *nvidia_compatible_1[]={ "@1,compatible","NVDA,NVMac" };
const char *nvidia_device_type_0[]={ "@0,device_type","display" };
const char *nvidia_device_type_1[]={ "@1,device_type","display" };
const char *nvidia_device_type[]={ "device_type","NVDA,Parent" };
const char *nvidia_name_0[]={ "@0,name","NVDA,Display-A" };
const char *nvidia_name_1[]={ "@1,name","NVDA,Display-B" };
const char *nvidia_slot_name[]={ "AAPL,slot-name","Slot-1" };
//const char *nvidia_display_cfg_0[] = { "@0,display-cfg
const char *nvidia_compatible_0[]={ "@0,compatible","NVDA,NVMac" };
const char *nvidia_compatible_1[]={ "@1,compatible","NVDA,NVMac" };
const char *nvidia_device_type_0[]={ "@0,device_type", "display" };
const char *nvidia_device_type_1[]={ "@1,device_type", "display" };
const char *nvidia_device_type[]={ "device_type","NVDA,Parent" };
const char *nvidia_name_0[]={ "@0,name","NVDA,Display-A" };
const char *nvidia_name_1[]={ "@1,name","NVDA,Display-B" };
const char *nvidia_slot_name[]={ "AAPL,slot-name", "Slot-1" };
static uint8_t default_NVCAP[]= {
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
static struct nv_chipsets_t NVKnownChipsets[] = {
{ 0x00000000, "Unknown" },
// temporary placement
{ 0x10DE0DF4, "GeForce GT 450M" }, //Azi + issue #99
{ 0x10DE1251, "GeForce GTX 560M" }, // Asus G74SX
//========================================
// 0040 - 004F
{ 0x10DE0040, "GeForce 6800 Ultra" },
{ 0x10DE0041, "GeForce 6800" },
static uint16_t read16(uint8_t *ptr, uint16_t offset)
{
uint8_t ret[2];
ret[0] = ptr[offset+1];
ret[1] = ptr[offset];
return *((uint16_t*)&ret);
}
return ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8 ) | ((x & 0x00FF0000) >> 8 ) | ((x & 0xFF000000) >> 24);
}
static uint8_t read8(uint8_t *ptr, uint16_t offset)
static uint8_tread8(uint8_t *ptr, uint16_t offset)
{
return ptr[offset];
}
static uint32_t read32(uint8_t *ptr, uint16_t offset)
{
uint8_t ret[4];
ret[0] = ptr[offset+3];
ret[1] = ptr[offset+2];
ret[2] = ptr[offset+1];
ret[3] = ptr[offset];
return *((uint32_t*)&ret);
}
#endif
}
uint16_t dcbptr = swap16(read16(rom, 0x36));
if(!dcbptr) {
if (!dcbptr) {
printf("no dcb table found\n");
return PATCH_ROM_FAILED;
}/* else
printf("dcb table at offset 0x%04x\n", dcbptr);
*/
uint8_t *dcbtable = &rom[dcbptr];
}
//else
//printf("dcb table at offset 0x%04x\n", dcbptr);
uint8_t *dcbtable = &rom[dcbptr];
uint8_t dcbtable_version = dcbtable[0];
uint8_t headerlength = 0;
uint8_t recordlength = 0;
uint8_t numentries = 0;
uint8_t headerlength = 0;
uint8_t numentries = 0;
uint8_t recordlength = 0;
if(dcbtable_version >= 0x20) {
if (dcbtable_version >= 0x20)
{
uint32_t sig;
if(dcbtable_version >= 0x30) {
if (dcbtable_version >= 0x30)
{
headerlength = dcbtable[1];
numentries = dcbtable[2];
numentries = dcbtable[2];
recordlength = dcbtable[3];
sig = *(uint32_t *)&dcbtable[6];
} else {
}
else
{
sig = *(uint32_t *)&dcbtable[4];
headerlength = 8;
}
if (sig != 0x4edcbdcb) {
//Azi: match this with one below and add line number ?
printf("Bad display config block signature (0x%8x)\n", sig);
if (sig != 0x4edcbdcb)
{
printf("Bad display config block signature (0x%8x)\n", sig); //Azi: issue #48
return PATCH_ROM_FAILED;
}
} else if (dcbtable_version >= 0x14) { /* some NV15/16, and NV11+ */
}
else if (dcbtable_version >= 0x14) /* some NV15/16, and NV11+ */
{
char sig[8] = { 0 };
strncpy(sig, (char *)&dcbtable[-7], 7);
recordlength = 10;
if (strcmp(sig, "DEV_REC")) {
if (strcmp(sig, "DEV_REC"))
{
printf("Bad Display Configuration Block signature (%s)\n", sig);
return PATCH_ROM_FAILED;
}
} else {
}
else
{
printf("ERROR: dcbtable_version is 0x%X\n", dcbtable_version);
return PATCH_ROM_FAILED;
}
if(numentries >= MAX_NUM_DCB_ENTRIES)
if (numentries >= MAX_NUM_DCB_ENTRIES)
numentries = MAX_NUM_DCB_ENTRIES;
uint8_t num_outputs = 0, i=0;
struct dcbentry {
uint8_t num_outputs = 0, i = 0;
struct dcbentry
{
uint8_t type;
uint8_t index;
uint8_t *heads;
} entries[numentries];
for (i = 0; i < numentries; i++) {
for (i = 0; i < numentries; i++)
{
uint32_t connection;
connection = *(uint32_t *)&dcbtable[headerlength + recordlength * i];
/* Should we allow discontinuous DCBs? Certainly DCB I2C tables can be discontinuous */
if ((connection & 0x0000000f) == 0x0000000f) /* end of records */
continue;
entries[num_outputs].type = connection & 0xf;
entries[num_outputs].index = num_outputs;
entries[num_outputs++].heads = (uint8_t*)&(dcbtable[(headerlength + recordlength * i) + 1]);
}
int has_lvds = false;
uint8_t channel1 = 0, channel2 = 0;
for(i=0; i<num_outputs; i++) {
if(entries[i].type == 3) {
for (i = 0; i < num_outputs; i++)
{
if (entries[i].type == 3)
{
has_lvds = true;
//printf("found LVDS\n");
channel1 |= ( 0x1 << entries[i].index);
entries[i].type = TYPE_GROUPED;
}
}
// if we have a LVDS output, we group the rest to the second channel
if(has_lvds) {
for(i=0; i<num_outputs; i++) {
if(entries[i].type == TYPE_GROUPED)
if (has_lvds)
{
for (i = 0; i < num_outputs; i++)
{
if (entries[i].type == TYPE_GROUPED)
continue;
channel2 |= ( 0x1 << entries[i].index);
entries[i].type = TYPE_GROUPED;
}
} else {
//
}
else
{
int x;
// we loop twice as we need to generate two channels
for(x=0; x<=1; x++) {
for(i=0; i<num_outputs; i++) {
if(entries[i].type == TYPE_GROUPED)
for (x = 0; x <= 1; x++)
{
for (i=0; i<num_outputs; i++)
{
if (entries[i].type == TYPE_GROUPED)
continue;
// if type is TMDS, the prior output is ANALOG
// we always group ANALOG and TMDS
// if there is a TV output after TMDS, we group it to that channel as well
if(i && entries[i].type == 0x2) {
switch (x) {
if (i && entries[i].type == 0x2)
{
switch (x)
{
case 0:
//printf("group channel 1\n");
channel1 |= ( 0x1 << entries[i].index);
entries[i].type = TYPE_GROUPED;
if((entries[i-1].type == 0x0)) {
if ((entries[i-1].type == 0x0))
{
channel1 |= ( 0x1 << entries[i-1].index);
entries[i-1].type = TYPE_GROUPED;
}
// group TV as well if there is one
if( ((i+1) < num_outputs) && (entries[i+1].type == 0x1) ) {
if ( ((i+1) < num_outputs) && (entries[i+1].type == 0x1) )
{
//printf("group tv1\n");
channel1 |= ( 0x1 << entries[i+1].index);
entries[i+1].type = TYPE_GROUPED;
}
break;
case 1:
//printf("group channel 2 : %d\n", i);
channel2 |= ( 0x1 << entries[i].index);
entries[i].type = TYPE_GROUPED;
if((entries[i-1].type == 0x0)) {
if ((entries[i - 1].type == 0x0))
{
channel2 |= ( 0x1 << entries[i-1].index);
entries[i-1].type = TYPE_GROUPED;
}
// group TV as well if there is one
if( ((i+1) < num_outputs) && (entries[i+1].type == 0x1) ) {
if ( ((i+1) < num_outputs) && (entries[i+1].type == 0x1) )
{
//printf("group tv2\n");
channel2 |= ( 0x1 << entries[i+1].index);
entries[i+1].type = TYPE_GROUPED;
}
break;
}
break;
}
// if we have left ungrouped outputs merge them to the empty channel
uint8_t *togroup;// = (channel1 ? (channel2 ? NULL : &channel2) : &channel1);
togroup = &channel2;
for(i=0; i<num_outputs;i++)
if(entries[i].type != TYPE_GROUPED) {
for (i = 0; i < num_outputs; i++)
{
if (entries[i].type != TYPE_GROUPED)
{
//printf("%d not grouped\n", i);
if(togroup)
if (togroup)
{
*togroup |= ( 0x1 << entries[i].index);
}
entries[i].type = TYPE_GROUPED;
}
}
if(channel1 > channel2) {
if (channel1 > channel2)
{
uint8_t buff = channel1;
channel1 = channel2;
channel2 = buff;
default_NVCAP[8] = channel2;
// patching HEADS
for(i=0; i<num_outputs;i++) {
if(channel1 & (1 << i))
for (i = 0; i < num_outputs; i++)
{
if (channel1 & (1 << i))
{
*entries[i].heads = 1;
}
else if(channel2 & (1 << i))
{
*entries[i].heads = 2;
}
}
return (has_lvds ? PATCH_ROM_SUCCESS_HAS_LVDS : PATCH_ROM_SUCCESS);
}
static char *get_nvidia_model(uint32_t id) {
inti;
for (i=1; i< (sizeof(NVKnownChipsets) / sizeof(NVKnownChipsets[0])); i++) {
if (NVKnownChipsets[i].device == id) {
static char *get_nvidia_model(uint32_t id)
{
int i;
for (i = 1; i < (sizeof(NVKnownChipsets) / sizeof(NVKnownChipsets[0])); i++) {
if (NVKnownChipsets[i].device == id)
{
return NVKnownChipsets[i].name;
}
}
static uint32_t load_nvidia_bios_file(const char *filename, uint8_t *buf, int bufsize)
{
intfd;
intsize;
if ((fd = open_bvdev("bt(0,0)", filename, 0)) < 0) {
int fd;
int size;
if ((fd = open_bvdev("bt(0,0)", filename, 0)) < 0)
{
return 0;
}
size = file_size(fd);
if (size > bufsize) {
printf("Filesize of %s is bigger than expected! Truncating to 0x%x Bytes!\n", filename, bufsize);
if (size > bufsize)
{
printf("Filesize of %s is bigger than expected! Truncating to 0x%x Bytes!\n",
filename, bufsize);
size = bufsize;
}
size = read(fd, (char *)buf, size);
close(fd);
return size > 0 ? size : 0;
}
static int devprop_add_nvidia_template(struct DevPropDevice *device)
{
chartmp[16];
if(!device)
char tmp[16];
if (!device)
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_compatible_0))
if (!DP_ADD_TEMP_VAL(device, nvidia_compatible_0))
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_device_type_0))
if (!DP_ADD_TEMP_VAL(device, nvidia_device_type_0))
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_name_0))
if (!DP_ADD_TEMP_VAL(device, nvidia_name_0))
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_compatible_1))
if (!DP_ADD_TEMP_VAL(device, nvidia_compatible_1))
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_device_type_1))
if (!DP_ADD_TEMP_VAL(device, nvidia_device_type_1))
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_name_1))
if (!DP_ADD_TEMP_VAL(device, nvidia_name_1))
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_device_type))
if (!DP_ADD_TEMP_VAL(device, nvidia_device_type))
return 0;
// Rek : Dont use sprintf return, it does not WORK !! our custom sprintf() always return 0!
// len = sprintf(tmp, "Slot-%x", devices_number);
sprintf(tmp, "Slot-%x",devices_number);
devprop_add_value(device, "AAPL,slot-name", (uint8_t *) tmp, strlen(tmp));
devices_number++;
return 1;
}
int hex2bin(const char *hex, uint8_t *bin, int len)
{
char*p;
inti;
inti;
charbuf[3];
if (hex == NULL || bin == NULL || len <= 0 || strlen(hex) != len * 2) {
buf[2] = '\0';
p = (char *) hex;
for (i=0; i<len; i++) {
for (i = 0; i < len; i++)
{
if (p[0] == '\0' || p[1] == '\0' || !isxdigit(p[0]) || !isxdigit(p[1])) {
printf("[ERROR] bin2hex '%s' syntax error\n", hex);
return -2;
{
unsigned long long vram_size = 0;
if (nvCardType < NV_ARCH_50) {
if (nvCardType < NV_ARCH_50)
{
vram_size = REG32(NV04_PFB_FIFO_DATA);
vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
}
else if (nvCardType < NV_ARCH_C0) {
else if (nvCardType < NV_ARCH_C0)
{
vram_size = REG32(NV04_PFB_FIFO_DATA);
vram_size |= (vram_size & 0xff) << 32;
vram_size &= 0xffffffff00ll;
}
else { // >= NV_ARCH_C0
else // >= NV_ARCH_C0
{
vram_size = REG32(NVC0_MEM_CTRLR_RAM_AMOUNT) << 20;
vram_size *= REG32(NVC0_MEM_CTRLR_COUNT);
}
// Workaround for GT 420/430 & 9600M GT
switch (nvda_dev->device_id)
{
case 0x0DE1: vram_size = 1024*1024*1024; break; // GT 430
case 0x0DE2: vram_size = 1024*1024*1024; break; // GT 420
case 0x0649: vram_size = 512*1024*1024; break; // 9600M GT
case 0x0649: vram_size = 512*1024*1024; break;// 9600M GT
default: break;
}
bool setup_nvidia_devprop(pci_dt_t *nvda_dev)
{
struct DevPropDevice*device;
char*devicepath;
option_rom_pci_header_t*rom_pci_header;
volatile uint8_t*regs;
uint8_t*rom;
uint8_t*nvRom;
uint8_tnvCardType;
unsigned long longvideoRam;
uint32_tnvBiosOveride;
uint32_tbar[7];
uint32_tboot_display;
intnvPatch;
intlen;
charbiosVersion[32];
charnvFilename[32];
charkNVCAP[12];
char*model;
const char*value;
booldoit;
struct DevPropDevice*device;
char*devicepath;
option_rom_pci_header_t *rom_pci_header;
volatile uint8_t*regs;
uint8_t*rom;
uint8_t*nvRom;
uint8_tnvCardType;
unsigned long longvideoRam;
uint32_tnvBiosOveride;
uint32_tbar[7];
uint32_tboot_display;
intnvPatch;
intlen;
charbiosVersion[32];
charnvFilename[32];
charkNVCAP[12];
char*model;
const char*value;
booldoit;
devicepath = get_pci_dev_path(nvda_dev);
bar[0] = pci_config_read32(nvda_dev->dev.addr, 0x10 );
regs = (uint8_t *) (bar[0] & ~0x0f);
// get card type
nvCardType = (REG32(0) >> 20) & 0x1ff;
// Amount of VRAM in kilobytes
videoRam = mem_detect(regs, nvCardType, nvda_dev);
model = get_nvidia_model((nvda_dev->vendor_id << 16) | nvda_dev->device_id);
verbose("nVidia %s %dMB NV%02x [%04x:%04x] :: %s\n",
verbose("nVidia %s %dMB NV%02x [%04x:%04x] :: %s\n",
model, (uint32_t)(videoRam / 1024 / 1024),
(REG32(0) >> 20) & 0x1ff, nvda_dev->vendor_id, nvda_dev->device_id,
devicepath);
rom = malloc(NVIDIA_ROM_SIZE);
sprintf(nvFilename, "/Extra/%04x_%04x.rom", (uint16_t)nvda_dev->vendor_id, (uint16_t)nvda_dev->device_id);
if (getBoolForKey(kUseNvidiaROM, &doit, &bootInfo->chameleonConfig) && doit) {
sprintf(nvFilename, "/Extra/%04x_%04x.rom", (uint16_t)nvda_dev->vendor_id,
(uint16_t)nvda_dev->device_id);
if (getBoolForKey(kUseNvidiaROM, &doit, &bootInfo->chameleonConfig) && doit)
{
verbose("Looking for nvidia video bios file %s\n", nvFilename);
nvBiosOveride = load_nvidia_bios_file(nvFilename, rom, NVIDIA_ROM_SIZE);
if (nvBiosOveride > 0) {
if (nvBiosOveride > 0)
{
verbose("Using nVidia Video BIOS File %s (%d Bytes)\n", nvFilename, nvBiosOveride);
DBG("%s Signature 0x%02x%02x %d bytes\n", nvFilename, rom[0], rom[1], nvBiosOveride);
} else {
}
else
{
printf("ERROR: unable to open nVidia Video BIOS File %s\n", nvFilename);
return false;
}
} else {
}
else
{
// Otherwise read bios from card
nvBiosOveride = 0;
// TODO: we should really check for the signature before copying the rom, i think.
// PRAMIN first
nvRom = (uint8_t*)&regs[NV_PRAMIN_OFFSET];
bcopy((uint32_t *)nvRom, rom, NVIDIA_ROM_SIZE);
// Valid Signature ?
if (rom[0] != 0x55 && rom[1] != 0xaa) {
if (rom[0] != 0x55 && rom[1] != 0xaa)
{
// PROM next
// Enable PROM access
(REG32(NV_PBUS_PCI_NV_20)) = NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED;
nvRom = (uint8_t*)&regs[NV_PROM_OFFSET];
bcopy((uint8_t *)nvRom, rom, NVIDIA_ROM_SIZE);
// disable PROM access
(REG32(NV_PBUS_PCI_NV_20)) = NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED;
(REG32(NV_PBUS_PCI_NV_20)) = NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED;
// Valid Signature ?
if (rom[0] != 0x55 && rom[1] != 0xaa) {
if (rom[0] != 0x55 && rom[1] != 0xaa)
{
// 0xC0000 last
bcopy((char *)0xc0000, rom, NVIDIA_ROM_SIZE);
// Valid Signature ?
if (rom[0] != 0x55 && rom[1] != 0xaa) {
if (rom[0] != 0x55 && rom[1] != 0xaa)
{
printf("ERROR: Unable to locate nVidia Video BIOS\n");
return false;
} else {
}
else
{
DBG("ROM Address 0x%x Signature 0x%02x%02x\n", nvRom, rom[0], rom[1]);
}
} else {
}
else
{
DBG("PROM Address 0x%x Signature 0x%02x%02x\n", nvRom, rom[0], rom[1]);
}
} else {
}
else
{
DBG("PRAM Address 0x%x Signature 0x%02x%02x\n", nvRom, rom[0], rom[1]);
}
}
if ((nvPatch = patch_nvidia_rom(rom)) == PATCH_ROM_FAILED) {
printf("ERROR: nVidia ROM Patching Failed!\n");
//return false;
}
rom_pci_header = (option_rom_pci_header_t*)(rom + *(uint16_t *)&rom[24]);
// check for 'PCIR' sig
if (rom_pci_header->signature == 0x50434952) {
if (rom_pci_header->device_id != nvda_dev->device_id) {
if (rom_pci_header->signature == 0x50434952)
{
if (rom_pci_header->device_id != nvda_dev->device_id)
{
// Get Model from the OpROM
model = get_nvidia_model((rom_pci_header->vendor_id << 16) | rom_pci_header->device_id);
} else {
}
else
{
printf("nVidia incorrect PCI ROM signature: 0x%x\n", rom_pci_header->signature);
}
}
if (!string) {
string = devprop_create_string();
}
device = devprop_add_device(string, devicepath);
/* FIXME: for primary graphics card only */
boot_display = 1;
devprop_add_value(device, "@0,AAPL,boot-display", (uint8_t*)&boot_display, 4);
if(nvPatch == PATCH_ROM_SUCCESS_HAS_LVDS) {
if (nvPatch == PATCH_ROM_SUCCESS_HAS_LVDS) {
uint8_t built_in = 0x01;
devprop_add_value(device, "@0,built-in", &built_in, 1);
}
// get bios version
const int MAX_BIOS_VERSION_LENGTH = 32;
char* version_str = (char*)malloc(MAX_BIOS_VERSION_LENGTH);
memset(version_str, 0, MAX_BIOS_VERSION_LENGTH);
int i, version_start;
int crlf_count = 0;
// only search the first 384 bytes
for(i = 0; i < 0x180; i++) {
if(rom[i] == 0x0D && rom[i+1] == 0x0A) {
for (i = 0; i < 0x180; i++)
{
if (rom[i] == 0x0D && rom[i+1] == 0x0A)
{
crlf_count++;
// second 0x0D0A was found, extract bios version
if(crlf_count == 2) {
if(rom[i-1] == 0x20) i--; // strip last " "
for(version_start = i; version_start > (i-MAX_BIOS_VERSION_LENGTH); version_start--) {
if (crlf_count == 2)
{
if (rom[i-1] == 0x20) i--; // strip last " "
for (version_start = i; version_start > (i-MAX_BIOS_VERSION_LENGTH); version_start--)
{
// find start
if(rom[version_start] == 0x00) {
if (rom[version_start] == 0x00)
{
version_start++;
// strip "Version "
if(strncmp((const char*)rom+version_start, "Version ", 8) == 0) {
if (strncmp((const char*)rom+version_start, "Version ", 8) == 0)
{
version_start += 8;
}
}
sprintf(biosVersion, "%s", (nvBiosOveride > 0) ? nvFilename : version_str);
sprintf(kNVCAP, "NVCAP_%04x", nvda_dev->device_id);
if (getValueForKey(kNVCAP, &value, &len, &bootInfo->chameleonConfig) && len == NVCAP_LEN * 2) {
uint8_tnew_NVCAP[NVCAP_LEN];
if (hex2bin(value, new_NVCAP, NVCAP_LEN) == 0) {
if (getValueForKey(kNVCAP, &value, &len, &bootInfo->chameleonConfig) && len == NVCAP_LEN * 2)
{
uint8_t new_NVCAP[NVCAP_LEN];
if (hex2bin(value, new_NVCAP, NVCAP_LEN) == 0)
{
verbose("Using user supplied NVCAP for %s :: %s\n", model, devicepath);
memcpy(default_NVCAP, new_NVCAP, NVCAP_LEN);
}
}
if (getValueForKey(kDcfg0, &value, &len, &bootInfo->chameleonConfig) && len == DCFG0_LEN * 2){
uint8_t new_dcfg0[DCFG0_LEN];
if (hex2bin(value, new_dcfg0, DCFG0_LEN) == 0)
{
memcpy(default_dcfg_0, new_dcfg0, DCFG0_LEN);
verbose("Using user supplied @0,display-cfg\n");
printf("@0,display-cfg: %02x%02x%02x%02x\n",
default_dcfg_0[0], default_dcfg_0[1], default_dcfg_0[2], default_dcfg_0[3]);
}
}
if (getValueForKey(kDcfg1, &value, &len, &bootInfo->chameleonConfig) && len == DCFG1_LEN * 2){
uint8_t new_dcfg1[DCFG1_LEN];
if (hex2bin(value, new_dcfg1, DCFG1_LEN) == 0)
{
memcpy(default_dcfg_1, new_dcfg1, DCFG1_LEN);
verbose("Using user supplied @1,display-cfg\n");
printf("@1,display-cfg: %02x%02x%02x%02x\n",
default_dcfg_1[0], default_dcfg_1[1], default_dcfg_1[2], default_dcfg_1[3]);
}
}
#if DEBUG_NVCAP
printf("NVCAP: %02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x\n",
default_NVCAP[0], default_NVCAP[1], default_NVCAP[2], default_NVCAP[3],
default_NVCAP[4], default_NVCAP[5], default_NVCAP[6], default_NVCAP[7],
default_NVCAP[8], default_NVCAP[9], default_NVCAP[10], default_NVCAP[11],
default_NVCAP[12], default_NVCAP[13], default_NVCAP[14], default_NVCAP[15],
default_NVCAP[16], default_NVCAP[17], default_NVCAP[18], default_NVCAP[19]);
if (getValueForKey(kDcfg0, &value, &len, &bootInfo->chameleonConfig) && len == DCFG0_LEN * 2)
{
uint8_t new_dcfg0[DCFG0_LEN];
if (hex2bin(value, new_dcfg0, DCFG0_LEN) == 0)
{
memcpy(default_dcfg_0, new_dcfg0, DCFG0_LEN);
verbose("Using user supplied @0,display-cfg\n");
printf("@0,display-cfg: %02x%02x%02x%02x\n",
default_dcfg_0[0], default_dcfg_0[1], default_dcfg_0[2], default_dcfg_0[3]);
}
}
if (getValueForKey(kDcfg1, &value, &len, &bootInfo->chameleonConfig) && len == DCFG1_LEN * 2)
{
uint8_t new_dcfg1[DCFG1_LEN];
if (hex2bin(value, new_dcfg1, DCFG1_LEN) == 0)
{
memcpy(default_dcfg_1, new_dcfg1, DCFG1_LEN);
verbose("Using user supplied @1,display-cfg\n");
printf("@1,display-cfg: %02x%02x%02x%02x\n",
default_dcfg_1[0], default_dcfg_1[1], default_dcfg_1[2], default_dcfg_1[3]);
}
}
#if DEBUG_NVCAP
printf("NVCAP: %02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x\n",
default_NVCAP[0], default_NVCAP[1], default_NVCAP[2], default_NVCAP[3],
default_NVCAP[4], default_NVCAP[5], default_NVCAP[6], default_NVCAP[7],
default_NVCAP[8], default_NVCAP[9], default_NVCAP[10], default_NVCAP[11],
default_NVCAP[12], default_NVCAP[13], default_NVCAP[14], default_NVCAP[15],
default_NVCAP[16], default_NVCAP[17], default_NVCAP[18], default_NVCAP[19]);
#endif
devprop_add_nvidia_template(device);
devprop_add_value(device, "VRAM,totalsize", (uint8_t*)&videoRam, 4);
devprop_add_value(device, "model", (uint8_t*)model, strlen(model) + 1);
devprop_add_value(device, "rom-revision", (uint8_t*)biosVersion, strlen(biosVersion) + 1);
devprop_add_value(device, "@0,display-cfg", default_dcfg_0, DCFG0_LEN);
devprop_add_value(device, "@1,display-cfg", default_dcfg_1, DCFG1_LEN);
//add HDMI Audio back to nvidia
//http://forge.voodooprojects.org/p/chameleon/issues/67/
// uint8_t connector_type_1[]= {0x00, 0x08, 0x00, 0x00};
// devprop_add_value(device, "@1,connector-type",connector_type_1, 4);
//end Nvidia HDMI Audio
if (getBoolForKey(kVBIOS, &doit, &bootInfo->chameleonConfig) && doit) {
devprop_add_value(device, "@0,display-cfg", default_dcfg_0, DCFG0_LEN);
devprop_add_value(device, "@1,display-cfg", default_dcfg_1, DCFG1_LEN);
//add HDMI Audio back to nvidia
//http://forge.voodooprojects.org/p/chameleon/issues/67/
//uint8_t connector_type_1[]= {0x00, 0x08, 0x00, 0x00};
//devprop_add_value(device, "@1,connector-type",connector_type_1, 4);
//end Nvidia HDMI Audio
if (getBoolForKey(kVBIOS, &doit, &bootInfo->chameleonConfig) && doit)
{
devprop_add_value(device, "vbios", rom, (nvBiosOveride > 0) ? nvBiosOveride : (rom[2] * 512));
}
stringdata = malloc(sizeof(uint8_t) * string->length);
memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
stringlength = string->length;
return true;
}
branches/azimutz/trunkAutoResolution/i386/libsaio/ati.c
55
66
77
8
9
108
119
1210
1311
1412
15
1613
1714
18
15
1916
20
21
22
17
18
19
2320
2421
2522
......
8582
8683
8784
88
85
8986
9087
9188
......
199196
200197
201198
202
203
204
205
206
199
200
201
202
203
207204
208205
209206
207
210208
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
389396
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
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
445
446
447
448
449
450
451
452
453
454
455
456
439457
440458
441459
442460
443
461
444462
445463
446464
447465
466
467
468
448469
449470
471
472
450473
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
497520
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
515538
516539
517
540
518541
519542
520543
521544
522545
523546
524
547
525548
526549
527550
528551
529552
530553
531
532554
533555
534556
535
557
536558
537559
538560
......
547569
548570
549571
550
551
552
572
573
574
553575
554
576
555577
556578
557
558
559
579
580
581
560582
561583
562584
563585
564586
565587
566
567
568
569
570
571
572
588
589
590
591
592
593
594
573595
574596
575597
......
588610
589611
590612
591
592
593
594
595
613
614
615
616
617
596618
597619
598620
599621
600622
601
623
602624
603625
604626
605627
606
628
607629
608630
609631
610
611
632
633
612634
613635
614
636
615637
616638
617639
618
640
619641
620642
621643
622
644
623645
624
646
625647
626648
627649
628650
629
651
630652
631653
632654
633655
634656
635657
636
658
637659
638660
639
661
640662
641663
642
664
643665
644666
645667
646668
647
669
648670
649671
650672
......
658680
659681
660682
661
683
662684
663685
664686
......
667689
668690
669691
670
692
671693
672694
673695
......
675697
676698
677699
678
700
679701
680702
681703
682
704
683705
684706
685707
686708
687709
688
689
690
691
692
693
710
711
712
713
714
694715
695716
696717
......
698719
699720
700721
701
722
702723
703724
704725
705726
706
727
707728
708729
709730
710
731
711732
712733
713734
......
715736
716737
717738
718
739
719740
720741
721742
722
743
723744
724745
725746
......
728749
729750
730751
731
752
732753
733754
734755
735756
736757
737
758
738759
739760
740761
741762
742
763
743764
744765
745766
......
748769
749770
750771
751
772
752773
753774
754775
......
772793
773794
774795
775
796
776797
777
798
778799
779800
780801
781
802
782803
783804
784805
......
787808
788809
789810
790
811
791812
792813
793814
......
795816
796817
797818
819
798820
799821
800822
......
802824
803825
804826
827
805828
829
806830
831
807832
808833
809834
810835
836
811837
812838
813839
......
825851
826852
827853
828
829
830
854
855
856
857
831858
832
859
860
833861
834862
835863
......
837865
838866
839867
840
841
842
868
869
870
843871
844872
845873
846874
847875
848876
877
878
849879
850880
851881
852882
853
854883
855884
856885
857886
858887
859888
860
889
861890
862
891
863892
864893
865
894
866895
867896
868
897
869898
870899
871900
872901
873902
874
903
875904
876905
877
906
878907
879908
880909
881
910
882911
883912
884913
885
914
886915
887916
888917
889918
890
919
891920
892921
893922
......
896925
897926
898927
899
928
900929
901
930
902931
903
932
904933
905934
906935
907936
908937
909938
910
939
911940
912
941
913942
914
915
943
944
916945
917946
918947
......
922951
923952
924953
925
954
926955
927956
928957
......
930959
931960
932961
933
962
934963
935964
936
965
937966
938967
939968
940
969
941970
942971
943972
944
973
945974
946
975
947976
948977
949978
......
951980
952981
953982
954
983
955984
956985
957986
958987
959988
960989
961
990
962991
963992
964993
965
966
994
995
967996
968
969
997
998
970999
971
972
1000
1001
9731002
9741003
9751004
976
1005
9771006
9781007
9791008
980
981
1009
1010
9821011
983
984
1012
1013
9851014
9861015
9871016
988
1017
9891018
9901019
9911020
9921021
993
1022
9941023
995
996
1024
1025
9971026
9981027
9991028
1000
1001
1029
1030
10021031
10031032
10041033
......
10161045
10171046
10181047
1019
1048
10201049
10211050
10221051
10231052
1024
1053
10251054
10261055
10271056
1028
1029
1057
1058
10301059
1031
1032
1060
1061
10331062
1034
1035
1063
1064
10361065
10371066
10381067
......
10431072
10441073
10451074
1046
1075
10471076
1048
1049
1077
1078
10501079
10511080
10521081
......
10591088
10601089
10611090
1062
10631091
10641092
10651093
......
10681096
10691097
10701098
1071
1072
1099
1100
10731101
10741102
10751103
1076
1077
1104
1105
10781106
10791107
10801108
1081
1109
10821110
10831111
1112
10841113
10851114
10861115
10871116
1088
1117
10891118
10901119
10911120
1092
1121
10931122
10941123
1095
1124
10961125
10971126
1127
10981128
10991129
11001130
11011131
11021132
11031133
1104
1105
1106
1107
1108
1134
1135
1136
1137
1138
1139
11091140
11101141
11111142
11121143
1113
1144
11141145
1115
1146
11161147
1148
11171149
11181150
11191151
1120
1152
11211153
11221154
11231155
1124
1156
1157
11251158
11261159
11271160
11281161
11291162
1130
1131
1163
11321164
11331165
11341166
1135
1136
1167
1168
11371169
1138
1139
1170
1171
11401172
11411173
11421174
1143
1175
11441176
1145
1177
11461178
1179
11471180
11481181
11491182
......
11531186
11541187
11551188
1156
1157
1158
1159
1160
1161
1162
11631189
1164
1165
1166
1190
1191
1192
11671193
11681194
11691195
......
11761202
11771203
11781204
1179
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
11801216
11811217
11821218
11831219
1184
1220
11851221
11861222
11871223
11881224
1189
1225
11901226
11911227
11921228
11931229
11941230
11951231
1196
1232
11971233
11981234
1199
1200
1201
1235
1236
1237
12021238
12031239
1204
1240
12051241
12061242
12071243
12081244
1209
1210
1245
1246
12111247
12121248
12131249
......
12161252
12171253
12181254
1219
1255
12201256
1221
1222
1223
1224
1257
1258
1259
1260
1261
12251262
12261263
1227
1228
1229
1230
1231
1264
1265
1266
1267
1268
12321269
1233
1270
12341271
1235
1272
12361273
1237
1274
12381275
12391276
1240
*
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "pci.h"
#include "platform.h"
#include "device_inject.h"
#include "ati_reg.h"
#defineOFFSET_TO_GET_ATOMBIOS_STRINGS_START0x6e
#define OFFSET_TO_GET_ATOMBIOS_STRINGS_START 0x6e
#define Reg32(reg)(*(volatile uint32_t *)(card->mmio + reg))
#define RegRead32(reg)(Reg32(reg))
#define RegWrite32(reg, value)(Reg32(reg) = value)
#define Reg32(reg)(*(volatile uint32_t *)(card->mmio + reg))
#define RegRead32(reg)(Reg32(reg))
#define RegWrite32(reg, value)(Reg32(reg) = value)
typedef enum {
kNul,
"Redwood",// RV830
"Juniper",// RV840
"Cypress",// RV870
"Hemlock",
"Hemlock",
/* Northern Islands */
"Barts",
"Caicos",
} config_name_t;
typedef struct {
uint16_tdevice_id;
uint32_tsubsys_id;
chip_family_tchip_family;
const char*model_name;
config_name_tcfg_name;
uint16_tdevice_id;
uint32_tsubsys_id;
chip_family_tchip_family;
const char*model_name;
config_name_tcfg_name;
} radeon_card_info_t;
static radeon_card_info_t radeon_cards[] = {
/* Earlier cards are not supported */
{ 0x9400,0x30001002,CHIP_FAMILY_R600,"ATI Radeon HD 2900 PRO",kNull},
{ 0x9400,0x25521002,CHIP_FAMILY_R600,"ATI Radeon HD 2900 XT",kNull},
{ 0x9440,0x24401682,CHIP_FAMILY_RV770,"ATI Radeon HD 4870",kMotmot},
{ 0x9440,0x24411682,CHIP_FAMILY_RV770,"ATI Radeon HD 4870",kMotmot},
{ 0x9440,0x24441682,CHIP_FAMILY_RV770,"ATI Radeon HD 4870",kMotmot},
{ 0x9440,0x24451682,CHIP_FAMILY_RV770,"ATI Radeon HD 4870",kMotmot},
{ 0x9441,0x24401682,CHIP_FAMILY_RV770,"ATI Radeon HD 4870 X2",kMotmot},
{ 0x9442,0x24701682,CHIP_FAMILY_RV770,"ATI Radeon HD 4850",kMotmot},
{ 0x9442,0x24711682,CHIP_FAMILY_RV770,"ATI Radeon HD 4850",kMotmot},
{ 0x9442,0x080110B0,CHIP_FAMILY_RV770,"ATI Radeon HD 4850",kMotmot},
{ 0x9442,0xE104174B,CHIP_FAMILY_RV770,"ATI Radeon HD 4850",kMotmot},
{ 0x944A,0x30001682,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001043,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001458,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001462,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001545,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001787,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x3000174B,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x300017AF,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944C,0x24801682,CHIP_FAMILY_RV770,"ATI Radeon HD 4830",kMotmot},
{ 0x944C,0x24811682,CHIP_FAMILY_RV770,"ATI Radeon HD 4830",kMotmot},
{ 0x944E,0x3260174B,CHIP_FAMILY_RV770,"ATI Radeon HD 4810 Series",kMotmot},
{ 0x944E,0x3261174B,CHIP_FAMILY_RV770,"ATI Radeon HD 4810 series",kMotmot},
{ 0x944E,0x30001787,CHIP_FAMILY_RV770,"ATI Radeon HD 4730 Series",kMotmot},
{ 0x944E,0x30101787,CHIP_FAMILY_RV770,"ATI Radeon HD 4810 Series",kMotmot},
{ 0x944E,0x31001787,CHIP_FAMILY_RV770,"ATI Radeon HD 4820",kMotmot},
{ 0x9490,0x30501787,CHIP_FAMILY_RV730,"ATI Radeon HD 4710",kNull},
{ 0x9490,0x4710174B,CHIP_FAMILY_RV730,"ATI Radeon HD 4710",kNull},
{ 0x9490,0x300017AF,CHIP_FAMILY_RV730,"ATI Radeon HD 4710",kNull},
{ 0x9498,0x30501787,CHIP_FAMILY_RV730,"ATI Radeon HD 4700",kNull},
{ 0x9498,0x31001787,CHIP_FAMILY_RV730,"ATI Radeon HD 4720",kNull},
{ 0x9498,0x24511682,CHIP_FAMILY_RV730,"ATI Radeon HD 4650",kNull},
{ 0x9498,0x24521682,CHIP_FAMILY_RV730,"ATI Radeon HD 4650",kNull},
{ 0x9498,0x24541682,CHIP_FAMILY_RV730,"ATI Radeon HD 4650",kNull},
{ 0x9498,0x29331682,CHIP_FAMILY_RV730,"ATI Radeon HD 4670",kNull},
{ 0x9498,0x29341682,CHIP_FAMILY_RV730,"ATI Radeon HD 4670",kNull},
{ 0x9498,0x21CF1458,CHIP_FAMILY_RV730,"ATI Radeon HD 4600 Series",kNull},
{ 0x94B3,0x29001682,CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94B3,0x1170174B,CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94B3,0x10020D00,CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94C1,0x10021002,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Pro",kNull},
{ 0x94C1,0x0D021002,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x0D021028,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Pro",kNull},
{ 0x94C1,0x0D021028,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x21741458,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x10401462,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x10331462,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x10331462,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x11101462,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C3,0x37161642,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x30001642,CHIP_FAMILY_RV610,"ATI Radeon HD 3410",kNull},
{ 0x94C3,0x03421002,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x30001025,CHIP_FAMILY_RV610,"ATI Radeon HD 2350 Series",kNull},
{ 0x94C3,0x04021028,CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x03021028,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x04021028,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x216A1458,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x21721458,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x30001458,CHIP_FAMILY_RV610,"ATI Radeon HD 3410",kNull},
{ 0x94C3,0x11041462,CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x10411462,CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x11051462,CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x10321462,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x30001462,CHIP_FAMILY_RV610,"ATI Radeon HD 3410",kNull},
{ 0x94C3,0x3000148C,CHIP_FAMILY_RV610,"ATI Radeon HD 2350 Series",kNull},
{ 0x94C3,0x2247148C,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 LE",kNull},
{ 0x94C3,0x3000174B,CHIP_FAMILY_RV610,"ATI Radeon HD 2350 Series",kNull},
{ 0x94C3,0xE400174B,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0xE370174B,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0xE400174B,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0xE370174B,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0xE400174B,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x203817AF,CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x30001787,CHIP_FAMILY_RV610,"ATI Radeon HD 2350 Series",kNull},
{ 0x94C3,0x22471787,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 LE",kNull},
{ 0x94C3,0x01011A93,CHIP_FAMILY_RV610,"Qimonda Radeon HD 2400 PRO",kNull},
{ 0x9501,0x30001002,CHIP_FAMILY_RV670,"ATI Radeon HD 3690",kNull},
{ 0x9501,0x25421002,CHIP_FAMILY_RV670,"ATI Radeon HD 3870",kNull},
{ 0x9501,0x4750174B,CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9501,0x3000174B,CHIP_FAMILY_RV670,"Sapphire Radeon HD 3690",kNull},
{ 0x9501,0x30001787,CHIP_FAMILY_RV670,"ATI Radeon HD 3690",kNull},
{ 0x9505,0x30001002,CHIP_FAMILY_RV670,"ATI Radeon HD 3690",kNull},
{ 0x9505,0x25421002,CHIP_FAMILY_RV670,"ATI Radeon HD 3850",kNull},
{ 0x9505,0x30011043,CHIP_FAMILY_RV670,"ATI Radeon HD 4730",kNull},
{ 0x9505,0x3000148C,CHIP_FAMILY_RV670,"ATI Radeon HD 3850",kNull},
{ 0x9505,0x3002148C,CHIP_FAMILY_RV670,"ATI Radeon HD 4730",kNull},
{ 0x9505,0x3001148C,CHIP_FAMILY_RV670,"ATI Radeon HD 4730",kNull},
{ 0x9505,0x3003148C,CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9505,0x3004148C,CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9505,0x4730174B,CHIP_FAMILY_RV670,"ATI Radeon HD 4730",kNull},
{ 0x9505,0x3010174B,CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9505,0x3001174B,CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9505,0x3000174B,CHIP_FAMILY_RV670,"Sapphire Radeon HD 3690",kNull},
{ 0x9505,0x30001787,CHIP_FAMILY_RV670,"ATI Radeon HD 3690",kNull},
{ 0x9505,0x301017AF,CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9540,0x4590174B,CHIP_FAMILY_RV710,"ATI Radeon HD 4590",kNull},
{ 0x9540,0x30501787,CHIP_FAMILY_RV710,"ATI Radeon HD 4590",kNull},
{ 0x954F,0x29201682,CHIP_FAMILY_RV710,"ATI Radeon HD 4550",kNull},
{ 0x954F,0x29211682,CHIP_FAMILY_RV710,"ATI Radeon HD 4550",kNull},
{ 0x954F,0x30901682,CHIP_FAMILY_RV710,"XFX Radeon HD 4570",kNull},
{ 0x954F,0x4450174B,CHIP_FAMILY_RV710,"ATI Radeon HD 4450",kNull},
{ 0x954F,0x3000174B,CHIP_FAMILY_RV710,"ATI Radeon HD 4520",kNull},
{ 0x954F,0x30501787,CHIP_FAMILY_RV710,"ATI Radeon HD 4450",kNull},
{ 0x954F,0x31001787,CHIP_FAMILY_RV710,"ATI Radeon HD 4520",kNull},
{ 0x954F,0x4570174B,CHIP_FAMILY_RV710,"Sapphire Radeon HD4570",kNull},
{ 0x954F,0x301017AF,CHIP_FAMILY_RV710,"ATI Radeon HD 4450",kNull},
{ 0x9552,0x3000148C,CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9552,0x3000174B,CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9552,0x30001787,CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9552,0x300017AF,CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9581,0x95811002,CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9581,0x3000148C,CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9583,0x3000148C,CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9588,0x01021A93,CHIP_FAMILY_RV630,"Qimonda Radeon HD 2600 XT",kNull},
{ 0x9589,0x30001462,CHIP_FAMILY_RV630,"ATI Radeon HD 3610",kNull},
{ 0x9589,0x30001642,CHIP_FAMILY_RV630,"ATI Radeon HD 3610",kNull},
{ 0x9589,0x0E41174B,CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9589,0x30001787,CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9589,0x01001A93,CHIP_FAMILY_RV630,"Qimonda Radeon HD 2600 PRO",kNull},
{ 0x9591,0x2303148C,CHIP_FAMILY_RV635,"ATI Radeon HD 3600 Series",kNull},
{ 0x9598,0xB3831002,CHIP_FAMILY_RV635,"ATI All-in-Wonder HD",kNull},
{ 0x9598,0x30011043,CHIP_FAMILY_RV635,"ATI Radeon HD 4570",kNull},
{ 0x9598,0x30001043,CHIP_FAMILY_RV635,"HD3730",kNull},
{ 0x9598,0x3000148C,CHIP_FAMILY_RV635,"ATI Radeon HD 3730",kNull},
{ 0x9598,0x3031148C,CHIP_FAMILY_RV635,"ATI Radeon HD 4570",kNull},
{ 0x9598,0x3001148C,CHIP_FAMILY_RV635,"ATI Radeon HD 4580",kNull},
{ 0x9598,0x30011545,CHIP_FAMILY_RV635,"VisionTek Radeon HD 2600 Pro",kNull},
{ 0x9598,0x30001545,CHIP_FAMILY_RV635,"VisionTek Radeon HD 2600 XT",kNull},
{ 0x9598,0x4570174B,CHIP_FAMILY_RV635,"ATI Radeon HD 4570",kNull},
{ 0x9598,0x4580174B,CHIP_FAMILY_RV635,"ATI Radeon HD 4580",kNull},
{ 0x9598,0x4610174B,CHIP_FAMILY_RV635,"ATI Radeon HD 4610",kNull},
{ 0x9598,0x3000174B,CHIP_FAMILY_RV635,"Sapphire Radeon HD 3730",kNull},
{ 0x9598,0x3001174B,CHIP_FAMILY_RV635,"Sapphire Radeon HD 3750",kNull},
{ 0x9598,0x301017AF,CHIP_FAMILY_RV635,"ATI Radeon HD 4570",kNull},
{ 0x9598,0x301117AF,CHIP_FAMILY_RV635,"ATI Radeon HD 4580",kNull},
{ 0x9598,0x300117AF,CHIP_FAMILY_RV635,"ATI Radeon HD3750",kNull},
{ 0x9598,0x30501787,CHIP_FAMILY_RV635,"ATI Radeon HD 4610",kNull},
{ 0x95C0,0x3000148C,CHIP_FAMILY_RV620,"ATI Radeon HD 3550",kNull},
{ 0x95C0,0xE3901745,CHIP_FAMILY_RV620,"ATI Radeon HD 3550",kNull},
{ 0x95C0,0x3002174B,CHIP_FAMILY_RV620,"ATI Radeon HD 3570",kNull},
{ 0x95C0,0x3020174B,CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C0,0x3000174B,CHIP_FAMILY_RV620,"Sapphire Radeon HD 3550",kNull},
{ 0x95C5,0x3000148C,CHIP_FAMILY_RV620,"ATI Radeon HD 3450",kNull},
{ 0x95C5,0x3001148C,CHIP_FAMILY_RV620,"ATI Radeon HD 3550",kNull},
{ 0x95C5,0x3002148C,CHIP_FAMILY_RV620,"ATI Radeon HD 4230",kNull},
{ 0x95C5,0x3033148C,CHIP_FAMILY_RV620,"ATI Radeon HD 4230",kNull},
{ 0x95C5,0x3003148C,CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x3032148C,CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x3010174B,CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x4250174B,CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x30501787,CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x301017AF,CHIP_FAMILY_RV620,"ATI Radeon HD 4230",kNull},
{ 0x95C5,0x01051A93,CHIP_FAMILY_RV620,"Qimonda Radeon HD 3450",kNull},
{ 0x95C5,0x01041A93,CHIP_FAMILY_RV620,"Qimonda Radeon HD 3450",kNull},
{ 0x9400,0x30001002, CHIP_FAMILY_R600,"ATI Radeon HD 2900 PRO",kNull},
{ 0x9400,0x25521002, CHIP_FAMILY_R600,"ATI Radeon HD 2900 XT",kNull},
{ 0x9440,0x24401682, CHIP_FAMILY_RV770,"ATI Radeon HD 4870",kMotmot},
{ 0x9440,0x24411682, CHIP_FAMILY_RV770,"ATI Radeon HD 4870",kMotmot},
{ 0x9440,0x24441682, CHIP_FAMILY_RV770,"ATI Radeon HD 4870",kMotmot},
{ 0x9440,0x24451682, CHIP_FAMILY_RV770,"ATI Radeon HD 4870",kMotmot},
{ 0x9441,0x24401682, CHIP_FAMILY_RV770,"ATI Radeon HD 4870 X2",kMotmot},
{ 0x9442,0x24701682, CHIP_FAMILY_RV770,"ATI Radeon HD 4850",kMotmot},
{ 0x9442,0x24711682, CHIP_FAMILY_RV770,"ATI Radeon HD 4850",kMotmot},
{ 0x9442,0x080110B0, CHIP_FAMILY_RV770,"ATI Radeon HD 4850",kMotmot},
{ 0x9442,0xE104174B, CHIP_FAMILY_RV770,"ATI Radeon HD 4850",kMotmot},
{ 0x944A,0x30001682, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001043, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001458, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001462, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001545, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x30001787, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x3000174B, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944A,0x300017AF, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944C,0x24801682, CHIP_FAMILY_RV770,"ATI Radeon HD 4830",kMotmot},
{ 0x944C,0x24811682, CHIP_FAMILY_RV770,"ATI Radeon HD 4830",kMotmot},
{ 0x944E,0x3260174B, CHIP_FAMILY_RV770,"ATI Radeon HD 4810 Series",kMotmot},
{ 0x944E,0x3261174B, CHIP_FAMILY_RV770,"ATI Radeon HD 4810 series",kMotmot},
{ 0x944E,0x30001787, CHIP_FAMILY_RV770,"ATI Radeon HD 4730 Series",kMotmot},
{ 0x944E,0x30101787, CHIP_FAMILY_RV770,"ATI Radeon HD 4810 Series",kMotmot},
{ 0x944E,0x31001787, CHIP_FAMILY_RV770,"ATI Radeon HD 4820",kMotmot},
{ 0x9480,0x3628103C,CHIP_FAMILY_RV730,"ATI Radeon HD 4650M",kGliff},
{ 0x9480,0x9035104D,CHIP_FAMILY_RV730,"ATI Radeon HD 4650M",kGliff},
{ 0x9490,0x20031787, CHIP_FAMILY_RV730,"ATI Radeon HD 4670",kFlicker},
{ 0x9490,0x30501787, CHIP_FAMILY_RV730,"ATI Radeon HD 4710",kNull},
{ 0x9490,0x4710174B, CHIP_FAMILY_RV730,"ATI Radeon HD 4710",kNull},
{ 0x9490,0x300017AF, CHIP_FAMILY_RV730,"ATI Radeon HD 4710",kNull},
{ 0x9498,0x30501787, CHIP_FAMILY_RV730,"ATI Radeon HD 4700",kNull},
{ 0x9498,0x31001787, CHIP_FAMILY_RV730,"ATI Radeon HD 4720",kNull},
{ 0x9498,0x24511682, CHIP_FAMILY_RV730,"ATI Radeon HD 4650",kNull},
{ 0x9498,0x24521682, CHIP_FAMILY_RV730,"ATI Radeon HD 4650",kNull},
{ 0x9498,0x24541682, CHIP_FAMILY_RV730,"ATI Radeon HD 4650",kNull},
{ 0x9498,0x29331682, CHIP_FAMILY_RV730,"ATI Radeon HD 4670",kNull},
{ 0x9498,0x29341682, CHIP_FAMILY_RV730,"ATI Radeon HD 4670",kNull},
{ 0x9498,0x21CF1458, CHIP_FAMILY_RV730,"ATI Radeon HD 4600 Series",kNull},
{ 0x94B3,0x29001682, CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94B3,0x1170174B, CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94B3,0x10020D00, CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94C1,0x10021002, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Pro",kNull},
{ 0x94C1,0x0D021002, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x0D021028, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Pro",kNull},
{ 0x94C1,0x0D021028, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x21741458, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x10401462, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x10331462, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x10331462, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C1,0x11101462, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 XT",kNull},
{ 0x94C3,0x37161642, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x30001642, CHIP_FAMILY_RV610,"ATI Radeon HD 3410",kNull},
{ 0x94C3,0x03421002, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x30001025, CHIP_FAMILY_RV610,"ATI Radeon HD 2350 Series",kNull},
{ 0x94C3,0x04021028, CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x03021028, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x04021028, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x216A1458, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x21721458, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x30001458, CHIP_FAMILY_RV610,"ATI Radeon HD 3410",kNull},
{ 0x94C3,0x11041462, CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x10411462, CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x11051462, CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x10321462, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x30001462, CHIP_FAMILY_RV610,"ATI Radeon HD 3410",kNull},
{ 0x94C3,0x3000148C, CHIP_FAMILY_RV610,"ATI Radeon HD 2350 Series",kNull},
{ 0x94C3,0x2247148C, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 LE",kNull},
{ 0x94C3,0x3000174B, CHIP_FAMILY_RV610,"ATI Radeon HD 2350 Series",kNull},
{ 0x94C3,0xE400174B, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0xE370174B, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0xE400174B, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0xE370174B, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0xE400174B, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 PRO",kNull},
{ 0x94C3,0x203817AF, CHIP_FAMILY_RV610,"ATI Radeon HD 2400",kNull},
{ 0x94C3,0x30001787, CHIP_FAMILY_RV610,"ATI Radeon HD 2350 Series",kNull},
{ 0x94C3,0x22471787, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 LE",kNull},
{ 0x94C3,0x01011A93, CHIP_FAMILY_RV610,"Qimonda Radeon HD 2400 PRO",kNull},
{ 0x9501,0x30001002, CHIP_FAMILY_RV670,"ATI Radeon HD 3690",kNull},
{ 0x9501,0x25421002, CHIP_FAMILY_RV670,"ATI Radeon HD 3870",kNull},
{ 0x9501,0x4750174B, CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9501,0x3000174B, CHIP_FAMILY_RV670,"Sapphire Radeon HD 3690",kNull},
{ 0x9501,0x30001787, CHIP_FAMILY_RV670,"ATI Radeon HD 3690",kNull},
{ 0x9505,0x30001002, CHIP_FAMILY_RV670,"ATI Radeon HD 3690",kNull},
{ 0x9505,0x25421002, CHIP_FAMILY_RV670,"ATI Radeon HD 3850",kNull},
{ 0x9505,0x30011043, CHIP_FAMILY_RV670,"ATI Radeon HD 4730",kNull},
{ 0x9505,0x3000148C, CHIP_FAMILY_RV670,"ATI Radeon HD 3850",kNull},
{ 0x9505,0x3002148C, CHIP_FAMILY_RV670,"ATI Radeon HD 4730",kNull},
{ 0x9505,0x3001148C, CHIP_FAMILY_RV670,"ATI Radeon HD 4730",kNull},
{ 0x9505,0x3003148C, CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9505,0x3004148C, CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9505,0x4730174B, CHIP_FAMILY_RV670,"ATI Radeon HD 4730",kNull},
{ 0x9505,0x3010174B, CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9505,0x3001174B, CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9505,0x3000174B, CHIP_FAMILY_RV670,"Sapphire Radeon HD 3690",kNull},
{ 0x9505,0x30001787, CHIP_FAMILY_RV670,"ATI Radeon HD 3690",kNull},
{ 0x9505,0x301017AF, CHIP_FAMILY_RV670,"ATI Radeon HD 4750",kNull},
{ 0x9540,0x4590174B, CHIP_FAMILY_RV710,"ATI Radeon HD 4590",kNull},
{ 0x9540,0x30501787, CHIP_FAMILY_RV710,"ATI Radeon HD 4590",kNull},
{ 0x954F,0x29201682, CHIP_FAMILY_RV710,"ATI Radeon HD 4550",kNull},
{ 0x954F,0x29211682, CHIP_FAMILY_RV710,"ATI Radeon HD 4550",kNull},
{ 0x954F,0x30901682, CHIP_FAMILY_RV710,"XFX Radeon HD 4570",kNull},
{ 0x954F,0x30501787, CHIP_FAMILY_RV710,"ATI Radeon HD 4450",kNull},
{ 0x954F,0x31001787, CHIP_FAMILY_RV710,"ATI Radeon HD 4520",kNull},
{ 0x954F,0x301017AF, CHIP_FAMILY_RV710,"ATI Radeon HD 4450",kNull},
{ 0x954F,0x4450174B, CHIP_FAMILY_RV710,"ATI Radeon HD 4450",kNull},
{ 0x954F,0x3000174B, CHIP_FAMILY_RV710,"ATI Radeon HD 4520",kNull},
{ 0x954F,0x4570174B, CHIP_FAMILY_RV710,"Sapphire Radeon HD 4570",kNull},
{ 0x954F,0xE990174B,CHIP_FAMILY_RV710,"Sapphire Radeon HD 4350",kNull},
{ 0x9552,0x3000148C, CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9552,0x3000174B, CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9552,0x30001787, CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9552,0x300017AF, CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9552,0x04341028, CHIP_FAMILY_RV710,"ATI Mobility Radeon 4330",kShrike},
{ 0x9553,0x1B321043, CHIP_FAMILY_RV710,"ATI Mobility Radeon HD 4570",kShrike/*??*/},
{ 0x9581,0x95811002, CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9581,0x3000148C, CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9583,0x3000148C, CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9588,0x01021A93, CHIP_FAMILY_RV630,"Qimonda Radeon HD 2600 XT",kNull},
{ 0x9589,0x30001462, CHIP_FAMILY_RV630,"ATI Radeon HD 3610",kNull},
{ 0x9589,0x30001642, CHIP_FAMILY_RV630,"ATI Radeon HD 3610",kNull},
{ 0x9589,0x0E41174B, CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9589,0x30001787, CHIP_FAMILY_RV630,"ATI Radeon HD 3600 Series",kNull},
{ 0x9589,0x01001A93, CHIP_FAMILY_RV630,"Qimonda Radeon HD 2600 PRO",kNull},
{ 0x9591,0x2303148C, CHIP_FAMILY_RV635,"ATI Radeon HD 3600 Series",kNull},
//Azi: most of the 9598 are rv630, according to http://developer.amd.com/gpu_assets/ATI_Device_IDs_xxx_xx.txt
{ 0x9598,0xB3831002, CHIP_FAMILY_RV635,"ATI All-in-Wonder HD",kNull},
{ 0x9598,0x30011043, CHIP_FAMILY_RV635,"ATI Radeon HD 4570",kNull},
{ 0x9598,0x30001043, CHIP_FAMILY_RV635,"HD3730",kNull},
{ 0x9598,0x3000148C, CHIP_FAMILY_RV635,"ATI Radeon HD 3730",kNull},
{ 0x9598,0x3031148C, CHIP_FAMILY_RV635,"ATI Radeon HD 4570",kNull},
{ 0x9598,0x3001148C, CHIP_FAMILY_RV635,"ATI Radeon HD 4580",kNull},
{ 0x9598,0x30011545, CHIP_FAMILY_RV635,"VisionTek Radeon HD 2600 Pro",kNull},
{ 0x9598,0x30001545, CHIP_FAMILY_RV635,"VisionTek Radeon HD 2600 XT",kNull},
{ 0x9598,0x4570174B, CHIP_FAMILY_RV635,"ATI Radeon HD 4570",kNull},
{ 0x9598,0x4580174B, CHIP_FAMILY_RV635,"ATI Radeon HD 4580",kNull},
{ 0x9598,0x4610174B, CHIP_FAMILY_RV635,"ATI Radeon HD 4610",kNull},
{ 0x9598,0x3000174B, CHIP_FAMILY_RV635,"Sapphire Radeon HD 3730",kNull},
{ 0x9598,0x3001174B, CHIP_FAMILY_RV635,"Sapphire Radeon HD 3750",kNull},
{ 0x9598,0x301017AF, CHIP_FAMILY_RV635,"ATI Radeon HD 4570",kNull},
{ 0x9598,0x301117AF, CHIP_FAMILY_RV635,"ATI Radeon HD 4580",kNull},
{ 0x9598,0x300117AF, CHIP_FAMILY_RV635,"ATI Radeon HD3750",kNull},
{ 0x9598,0x30501787, CHIP_FAMILY_RV635,"ATI Radeon HD 4610",kNull},
{ 0x95C0,0x3000148C, CHIP_FAMILY_RV620,"ATI Radeon HD 3550",kNull},
{ 0x95C0,0xE3901745, CHIP_FAMILY_RV620,"ATI Radeon HD 3550",kNull},
{ 0x95C0,0x3002174B, CHIP_FAMILY_RV620,"ATI Radeon HD 3570",kNull},
{ 0x95C0,0x3020174B, CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C0,0x3000174B, CHIP_FAMILY_RV620,"Sapphire Radeon HD 3550",kNull},
{ 0x95C5,0x3000148C, CHIP_FAMILY_RV620,"ATI Radeon HD 3450",kNull},
{ 0x95C5,0x3001148C, CHIP_FAMILY_RV620,"ATI Radeon HD 3550",kNull},
{ 0x95C5,0x3002148C, CHIP_FAMILY_RV620,"ATI Radeon HD 4230",kNull},
{ 0x95C5,0x3033148C, CHIP_FAMILY_RV620,"ATI Radeon HD 4230",kNull},
{ 0x95C5,0x3003148C, CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x3032148C, CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x3010174B, CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x4250174B, CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x30501787, CHIP_FAMILY_RV620,"ATI Radeon HD 4250",kNull},
{ 0x95C5,0x301017AF, CHIP_FAMILY_RV620,"ATI Radeon HD 4230",kNull},
{ 0x95C5,0x01051A93, CHIP_FAMILY_RV620,"Qimonda Radeon HD 3450",kNull},
{ 0x95C5,0x01041A93, CHIP_FAMILY_RV620,"Qimonda Radeon HD 3450",kNull},
/* Evergreen */
{ 0x6898,0x032E1043,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kUakari},
{ 0x6898,0xE140174B,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kUakari},
{ 0x6898,0x29611682,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kUakari},
{ 0x6898,0x0B001002,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kZonalis},
{ 0x6898,0x00D0106B,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kLangur},
{ 0x6899,0x21E41458,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5850",kUakari},
{ 0x6899,0x200A1787,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5850",kUakari},
{ 0x6899,0x22901787,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5850",kUakari},
{ 0x6899,0xE140174B,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5850",kUakari},
{ 0x689C,0x03521043,CHIP_FAMILY_HEMLOCK,"ASUS ARES",kUakari},
{ 0x689C,0x039E1043,CHIP_FAMILY_HEMLOCK,"ASUS EAH5870 Series",kUakari},
{ 0x689C,0x30201682,CHIP_FAMILY_HEMLOCK,"ATI Radeon HD 5970",kUakari},
{ 0x68B8,0xE147174B,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x21D71458,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x1482174B,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x29901682,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x29911682,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x200B1787,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x22881787,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x00CF106B,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kHoolock},
{ 0x68D8,0x301117AF,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5690",kNull},
{ 0x68D8,0x301017AF,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5730",kNull},
{ 0x68D8,0x30001787,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5730",kNull},
{ 0x68D8,0x5690174B,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5690",kNull},
{ 0x68D8,0x5730174B,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5730",kNull},
{ 0x68D8,0x21D91458,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5670",kBaboon},
{ 0x68D8,0x03561043,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5670",kBaboon},
{ 0x68D8,0xE151174B,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5670",kBaboon},
{ 0x68D9,0x301017AF,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5630",kNull},
{ 0x68DA,0x301017AF,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5630",kNull},
{ 0x68DA,0x30001787,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5630",kNull},
{ 0x68DA,0x5630174B,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5630",kNull},
{ 0x68E0,0x04561028,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470M",kEulemur},
{ 0x68E1,0x1426103C,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5430M",kEulemur},
{ 0x68F9,0x301317AF,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470",kNull},
{ 0x68F9,0x301117AF,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470",kNull},
{ 0x68F9,0x301217AF,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5490",kNull},
{ 0x68F9,0x30001787,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470",kNull},
{ 0x68F9,0x30021787,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5490",kNull},
{ 0x68F9,0x30011787,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5530",kNull},
{ 0x68F9,0x5470174B,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470",kNull},
{ 0x68F9,0x5490174B,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5490",kNull},
{ 0x68F9,0x5530174B,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5530",kNull},
{ 0x6898,0x032E1043, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kUakari},
{ 0x6898,0xE140174B, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kUakari},
{ 0x6898,0x29611682, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kUakari},
{ 0x6898,0x0B001002, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kZonalis},
{ 0x6898,0x00D0106B, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5870",kLangur},
{ 0x6899,0x21E41458, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5850",kUakari},
{ 0x6899,0x200A1787, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5850",kUakari},
{ 0x6899,0x22901787, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5850",kUakari},
{ 0x6899,0xE140174B, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5850",kUakari},
{ 0x689C,0x03521043, CHIP_FAMILY_HEMLOCK,"ASUS ARES",kUakari},
{ 0x689C,0x039E1043, CHIP_FAMILY_HEMLOCK,"ASUS EAH5870 Series",kUakari},
{ 0x689C,0x30201682, CHIP_FAMILY_HEMLOCK,"ATI Radeon HD 5970",kUakari},
{ 0x68A8,0x050E1025,CHIP_FAMILY_CYPRESS,"AMD Radeon HD 6850M",kUakari}, // issue #89
{ 0x68B8,0xE147174B, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x21D71458, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x1482174B, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x29901682, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x29911682, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x200B1787, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x22881787, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kVervet},
{ 0x68B8,0x00CF106B, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5770",kHoolock},
{ 0x68C0,0x1594103C,CHIP_FAMILY_REDWOOD,"AMD Radeon HD 6570M",kNull}, // issue #91
//Azi: from Slice { 0x100268C0, "ATI Radeon 5670 Series", "Galago"}
// http://www.insanelymac.com/forum/index.php?s=&showtopic=255866&view=findpost&p=1695482
{ 0x68C1,0x033E1025,CHIP_FAMILY_REDWOOD,"ATI Mobility Radeon HD 5650",kNull},
{ 0x68D8,0x301117AF, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5690",kNull},
{ 0x68D8,0x301017AF, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5730",kNull},
{ 0x68D8,0x30001787, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5730",kNull},
{ 0x68D8,0x5690174B, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5690",kNull},
{ 0x68D8,0x5730174B, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5730",kNull},
{ 0x68D8,0x21D91458, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5670",kBaboon},
{ 0x68D8,0x03561043, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5670",kBaboon},
{ 0x68D8,0xE151174B, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5670",kBaboon},
{ 0x68D9,0x301017AF, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5630",kNull},
{ 0x68DA,0x301017AF, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5630",kNull},
{ 0x68DA,0x30001787, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5630",kNull},
{ 0x68DA,0x5630174B, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5630",kNull},
{ 0x68E1,0x1426103C, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5430M",kEulemur},
{ 0x68E0,0x1433103C, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470M",kEulemur},
{ 0x68E0,0x04561028, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470M",kEulemur},
{ 0x68F9, 0x20091787, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5450", kEulemur },
{ 0x68F9, 0x22911787, CHIP_FAMILY_CEDAR, "ATI Radeon HD 5450", kEulemur },
{ 0x68F9,0x301317AF, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470",kNull},
{ 0x68F9,0x301117AF, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470",kNull},
{ 0x68F9,0x30001787, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470",kNull},
{ 0x68F9,0x5470174B, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5470",kNull},
{ 0x68F9,0x301217AF, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5490",kNull},
{ 0x68F9,0x30021787, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5490",kNull},
{ 0x68F9,0x5490174B, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5490",kNull},
{ 0x68F9,0x5530174B, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5530",kNull},
{ 0x68F9,0x30011787, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5530",kNull},
/* Northen Islands */
{ 0x6718,0x0B001002,CHIP_FAMILY_CAYMAN,"AMD Radeon HD 6970",kNull},
{ 0x6718,0x31301682,CHIP_FAMILY_CAYMAN,"AMD Radeon HD 6970",kNull},
{ 0x6718,0x67181002,CHIP_FAMILY_CAYMAN,"AMD Radeon HD 6970",kNull},
{ 0x6738,0x67381002,CHIP_FAMILY_BARTS,"AMD Radeon HD 6870",kDuckweed},
{ 0x6739,0x67391002,CHIP_FAMILY_BARTS,"AMD Radeon HD 6850",kDuckweed},
{ 0x6739,0x21F81458,CHIP_FAMILY_BARTS,"AMD Radeon HD 6850",kDuckweed},
{ 0x6741,0x050E1025,CHIP_FAMILY_TURKS,"AMD Radeon HD 6650M",kNull}, // issue 121
{ 0x6741,0x1646103C,CHIP_FAMILY_TURKS,"AMD Radeon HD 6750M",kNull}, // issue 88
{ 0x6759,0xE193174B,CHIP_FAMILY_TURKS,"AMD Radeon HD 6570",kNull},
{ 0x6760,0x1CB21043,CHIP_FAMILY_RV730,"AMD Radeon HD 6470M",kNull},
/* standard/default models */
{ 0x9400,0x00000000,CHIP_FAMILY_R600,"ATI Radeon HD 2900 XT",kNull},
{ 0x9405,0x00000000,CHIP_FAMILY_R600,"ATI Radeon HD 2900 GT",kNull},
{ 0x9440,0x00000000,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x9441,0x00000000,CHIP_FAMILY_RV770,"ATI Radeon HD 4870 X2",kMotmot},
{ 0x9442,0x00000000,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x9443,0x00000000,CHIP_FAMILY_RV770,"ATI Radeon HD 4850 X2",kMotmot},
{ 0x944C,0x00000000,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944E,0x00000000,CHIP_FAMILY_RV770,"ATI Radeon HD 4700 Series",kMotmot},
{ 0x9450,0x00000000,CHIP_FAMILY_RV770,"AMD FireStream 9270",kMotmot},
{ 0x9452,0x00000000,CHIP_FAMILY_RV770,"AMD FireStream 9250",kMotmot},
{ 0x9460,0x00000000,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x9462,0x00000000,CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x9490,0x00000000,CHIP_FAMILY_RV730,"ATI Radeon HD 4600 Series",kFlicker},
{ 0x9498,0x00000000,CHIP_FAMILY_RV730,"ATI Radeon HD 4600 Series",kFlicker},
{ 0x94B3,0x00000000,CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94B4,0x00000000,CHIP_FAMILY_RV740,"ATI Radeon HD 4700 Series",kFlicker},
{ 0x94B5,0x00000000,CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94C1,0x00000000,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Series",kIago},
{ 0x94C3,0x00000000,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Series",kIago},
{ 0x94C7,0x00000000,CHIP_FAMILY_RV610,"ATI Radeon HD 2350",kIago},
{ 0x94CC,0x00000000,CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Series",kIago},
{ 0x9501,0x00000000,CHIP_FAMILY_RV670,"ATI Radeon HD 3800 Series",kMegalodon},
{ 0x9505,0x00000000,CHIP_FAMILY_RV670,"ATI Radeon HD 3800 Series",kMegalodon},
{ 0x9507,0x00000000,CHIP_FAMILY_RV670,"ATI Radeon HD 3830",kMegalodon},
{ 0x950F,0x00000000,CHIP_FAMILY_RV670,"ATI Radeon HD 3870 X2",kMegalodon},
{ 0x9513,0x00000000,CHIP_FAMILY_RV670,"ATI Radeon HD 3850 X2",kMegalodon},
{ 0x9519,0x00000000,CHIP_FAMILY_RV670,"AMD FireStream 9170",kMegalodon},
{ 0x9540,0x00000000,CHIP_FAMILY_RV710,"ATI Radeon HD 4550",kNull},
{ 0x954F,0x00000000,CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9588,0x00000000,CHIP_FAMILY_RV630,"ATI Radeon HD 2600 XT",kLamna},
{ 0x9589,0x00000000,CHIP_FAMILY_RV630,"ATI Radeon HD 2600 PRO",kLamna},
{ 0x958A,0x00000000,CHIP_FAMILY_RV630,"ATI Radeon HD 2600 X2 Series",kLamna},
{ 0x9598,0x00000000,CHIP_FAMILY_RV635,"ATI Radeon HD 3600 Series",kMegalodon},
{ 0x95C0,0x00000000,CHIP_FAMILY_RV620,"ATI Radeon HD 3400 Series",kIago},
{ 0x95C5,0x00000000,CHIP_FAMILY_RV620,"ATI Radeon HD 3400 Series",kIago},
{ 0x9610,0x00000000,CHIP_FAMILY_RS780,"ATI Radeon HD 3200 Graphics",kNull},
{ 0x9611,0x00000000,CHIP_FAMILY_RS780,"ATI Radeon 3100 Graphics",kNull},
{ 0x9614,0x00000000,CHIP_FAMILY_RS780,"ATI Radeon HD 3300 Graphics",kNull},
{ 0x9616,0x00000000,CHIP_FAMILY_RS780,"AMD 760G",kNull},
{ 0x9710,0x00000000,CHIP_FAMILY_RS880,"ATI Radeon HD 4200",kNull},
{ 0x9715,0x00000000,CHIP_FAMILY_RS880,"ATI Radeon HD 4250",kNull},
{ 0x9714,0x00000000,CHIP_FAMILY_RS880,"ATI Radeon HD 4290",kNull},
{ 0x9400,0x00000000, CHIP_FAMILY_R600,"ATI Radeon HD 2900 XT",kNull},
{ 0x9405,0x00000000, CHIP_FAMILY_R600,"ATI Radeon HD 2900 GT",kNull},
{ 0x9440,0x00000000, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x9441,0x00000000, CHIP_FAMILY_RV770,"ATI Radeon HD 4870 X2",kMotmot},
{ 0x9442,0x00000000, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x9443,0x00000000, CHIP_FAMILY_RV770,"ATI Radeon HD 4850 X2",kMotmot},
{ 0x944C,0x00000000, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x944E,0x00000000, CHIP_FAMILY_RV770,"ATI Radeon HD 4700 Series",kMotmot},
{ 0x9450,0x00000000, CHIP_FAMILY_RV770,"AMD FireStream 9270",kMotmot},
{ 0x9452,0x00000000, CHIP_FAMILY_RV770,"AMD FireStream 9250",kMotmot},
{ 0x9460,0x00000000, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x9462,0x00000000, CHIP_FAMILY_RV770,"ATI Radeon HD 4800 Series",kMotmot},
{ 0x9490,0x00000000, CHIP_FAMILY_RV730,"ATI Radeon HD 4600 Series",kFlicker},
{ 0x9498,0x00000000, CHIP_FAMILY_RV730,"ATI Radeon HD 4600 Series",kFlicker},
{ 0x94B3,0x00000000, CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94B4,0x00000000, CHIP_FAMILY_RV740,"ATI Radeon HD 4700 Series",kFlicker},
{ 0x94B5,0x00000000, CHIP_FAMILY_RV740,"ATI Radeon HD 4770",kFlicker},
{ 0x94C1,0x00000000, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Series",kIago},
{ 0x94C3,0x00000000, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Series",kIago},
{ 0x94C7,0x00000000, CHIP_FAMILY_RV610,"ATI Radeon HD 2350",kIago},
{ 0x94CC,0x00000000, CHIP_FAMILY_RV610,"ATI Radeon HD 2400 Series",kIago},
{ 0x9501,0x00000000, CHIP_FAMILY_RV670,"ATI Radeon HD 3800 Series",kMegalodon},
{ 0x9505,0x00000000, CHIP_FAMILY_RV670,"ATI Radeon HD 3800 Series",kMegalodon},
{ 0x9507,0x00000000, CHIP_FAMILY_RV670,"ATI Radeon HD 3830",kMegalodon},
{ 0x950F,0x00000000, CHIP_FAMILY_RV670,"ATI Radeon HD 3870 X2",kMegalodon},
{ 0x9513,0x00000000, CHIP_FAMILY_RV670,"ATI Radeon HD 3850 X2",kMegalodon},
{ 0x9519,0x00000000, CHIP_FAMILY_RV670,"AMD FireStream 9170",kMegalodon},
{ 0x9540,0x00000000, CHIP_FAMILY_RV710,"ATI Radeon HD 4550",kNull},
{ 0x954F,0x00000000, CHIP_FAMILY_RV710,"ATI Radeon HD 4300/4500 Series",kNull},
{ 0x9588,0x00000000, CHIP_FAMILY_RV630,"ATI Radeon HD 2600 XT",kLamna},
{ 0x9589,0x00000000, CHIP_FAMILY_RV630,"ATI Radeon HD 2600 PRO",kLamna},
{ 0x958A,0x00000000, CHIP_FAMILY_RV630,"ATI Radeon HD 2600 X2 Series",kLamna},
{ 0x9598,0x00000000, CHIP_FAMILY_RV635,"ATI Radeon HD 3600 Series",kMegalodon},
{ 0x95C0,0x00000000, CHIP_FAMILY_RV620,"ATI Radeon HD 3400 Series",kIago},
{ 0x95C5,0x00000000, CHIP_FAMILY_RV620,"ATI Radeon HD 3400 Series",kIago},
{ 0x9610,0x00000000, CHIP_FAMILY_RS780,"ATI Radeon HD 3200 Graphics",kNull},
{ 0x9611,0x00000000, CHIP_FAMILY_RS780,"ATI Radeon 3100 Graphics",kNull},
{ 0x9614,0x00000000, CHIP_FAMILY_RS780,"ATI Radeon HD 3300 Graphics",kNull},
{ 0x9616,0x00000000, CHIP_FAMILY_RS780,"AMD 760G",kNull},
{ 0x9710,0x00000000, CHIP_FAMILY_RS880,"ATI Radeon HD 4200",kNull},
{ 0x9715,0x00000000, CHIP_FAMILY_RS880,"ATI Radeon HD 4250",kNull},
{ 0x9714,0x00000000, CHIP_FAMILY_RS880,"ATI Radeon HD 4290",kNull},
/* Evergreen */
{ 0x688D,0x00000000,CHIP_FAMILY_CYPRESS,"AMD FireStream 9350",kUakari},
{ 0x6898,0x00000000,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5800 Series",kUakari},
{ 0x6899,0x00000000,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5800 Series",kUakari},
{ 0x689E,0x00000000,CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5800 Series",kUakari},
{ 0x689C,0x00000000,CHIP_FAMILY_HEMLOCK,"ATI Radeon HD 5900 Series",kUakari},
{ 0x68B9,0x00000000,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5600 Series",kVervet},
{ 0x68B8,0x00000000,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5700 Series",kVervet},
{ 0x68BE,0x00000000,CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5700 Series",kVervet},
{ 0x68D8,0x00000000,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5600 Series",kBaboon},
{ 0x68D9,0x00000000,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5500 Series",kBaboon},
{ 0x68DA,0x00000000,CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5500 Series",kBaboon},
{ 0x68F9,0x00000000,CHIP_FAMILY_CEDAR,"ATI Radeon HD 5400 Series",kNull},
{ 0x688D,0x00000000, CHIP_FAMILY_CYPRESS,"AMD FireStream 9350",kUakari},
{ 0x6898,0x00000000, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5800 Series",kUakari},
{ 0x6899,0x00000000, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5800 Series",kUakari},
{ 0x689E,0x00000000, CHIP_FAMILY_CYPRESS,"ATI Radeon HD 5800 Series",kUakari},
{ 0x689C,0x00000000, CHIP_FAMILY_HEMLOCK,"ATI Radeon HD 5900 Series",kUakari},
{ 0x68B9,0x00000000, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5600 Series",kVervet},
{ 0x68B8,0x00000000, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5700 Series",kVervet},
{ 0x68BE,0x00000000, CHIP_FAMILY_JUNIPER,"ATI Radeon HD 5700 Series",kVervet},
{ 0x68D8,0x00000000, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5600 Series",kBaboon},
{ 0x68D9,0x00000000, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5500 Series",kBaboon},
{ 0x68DA,0x00000000, CHIP_FAMILY_REDWOOD,"ATI Radeon HD 5500 Series",kBaboon},
{ 0x68F9,0x00000000, CHIP_FAMILY_CEDAR,"ATI Radeon HD 5400 Series",kNull},
/* Northen Islands */
{ 0x6718,0x00000000,CHIP_FAMILY_CAYMAN,"AMD Radeon HD 6970 Series",kNull},
{ 0x6738,0x00000000,CHIP_FAMILY_BARTS,"AMD Radeon HD 6870 Series",kDuckweed},
{ 0x6739,0x00000000,CHIP_FAMILY_BARTS,"AMD Radeon HD 6850 Series",kDuckweed},
{ 0x673E,0x00000000,CHIP_FAMILY_BARTS,"AMD Radeon HD 6790 Series",kNull},
{ 0x6758,0x00000000,CHIP_FAMILY_TURKS,"AMD Radeon HD 6670 Series",kNull},
{ 0x6759,0x00000000,CHIP_FAMILY_TURKS,"AMD Radeon HD 6500 Series",kNull},
{ 0x6770,0x00000000,CHIP_FAMILY_CAICOS,"AMD Radeon HD 6400 Series",kNull},
{ 0x6779,0x00000000,CHIP_FAMILY_CAICOS,"AMD Radeon HD 6450 Series",kNull},
{ 0x0000,0x00000000,CHIP_FAMILY_UNKNOW,NULL,kNull}
};
typedef struct {
struct DevPropDevice*device;
radeon_card_info_t*info;
pci_dt_t *pci_dev;
pci_dt_t*pci_dev;
uint8_t*fb;
uint8_t*mmio;
uint8_t*io;
card_t *card;
/* Flags */
#define MKFLAG(n)(1 << n)
#define FLAGTRUEMKFLAG(0)
#define EVERGREENMKFLAG(1)
#define MKFLAG(n)(1 << n)
#define FLAGTRUEMKFLAG(0)
#define EVERGREENMKFLAG(1)
static uint8_t atN = 0;
//static uint8_t atN = 0;
typedef struct {
type_ttype;
uint32_tsize;
uint8_t*data;
type_ttype;
uint32_tsize;
uint8_t*data;
} value_t;
static value_t aty_name;
static value_t aty_nameparent;
//static value_t aty_model;
#define DATVAL(x){kPtr, sizeof(x), (uint8_t *)x}
#define STRVAL(x){kStr, sizeof(x), (uint8_t *)x}
#define BYTVAL(x){kCst, 1, (uint8_t *)x}
#define WRDVAL(x){kCst, 2, (uint8_t *)x}
#define DWRVAL(x){kCst, 4, (uint8_t *)x}
#define QWRVAL(x){kCst, 8, (uint8_t *)x}
#define NULVAL{kNul, 0, (uint8_t *)NULL}
#define DATVAL(x){kPtr, sizeof(x), (uint8_t *)x}
#define STRVAL(x){kStr, sizeof(x), (uint8_t *)x}
#define BYTVAL(x){kCst, 1, (uint8_t *)x}
#define WRDVAL(x){kCst, 2, (uint8_t *)x}
#define DWRVAL(x){kCst, 4, (uint8_t *)x}
#define QWRVAL(x){kCst, 8, (uint8_t *)x}
#define NULVAL{kNul, 0, (uint8_t *)NULL}
bool get_bootdisplay_val(value_t *val);
bool get_vrammemory_val(value_t *val);
bool get_vramtotalsize_val(value_t *val);
typedef struct {
uint32_tflags;
boolall_ports;
char*name;
bool(*get_value)(value_t *val);
value_tdefault_val;
uint32_tflags;
boolall_ports;
char*name;
bool(*get_value)(value_t *val);
value_tdefault_val;
} dev_prop_t;
dev_prop_t ati_devprop_list[] = {
{FLAGTRUE,false,"@0,AAPL,boot-display",get_bootdisplay_val,NULVAL},
//{FLAGTRUE,false,"@0,ATY,EFIDisplay",NULL,STRVAL("TMDSA")},
//{FLAGTRUE,true,"@0,AAPL,vram-memory",get_vrammemory_val,NULVAL},
//{FLAGTRUE,true,"@0,compatible",get_name_val,NULVAL},
//{FLAGTRUE,true,"@0,connector-type",get_conntype_val,NULVAL},
//{FLAGTRUE,true,"@0,device_type",NULL,STRVAL("display")},
//{FLAGTRUE,false,"@0,display-connect-flags",NULL,DWRVAL((uint32_t)0)},
//{FLAGTRUE,false,"@0,display-connect-flags", NULL,DWRVAL((uint32_t)0)},
//{FLAGTRUE,true,"@0,display-type",NULL,STRVAL("NONE")},
{FLAGTRUE,true,"@0,name",get_name_val,NULVAL},
//{FLAGTRUE,true,"@0,VRAM,memsize",get_vrammemsize_val,NULVAL},
//{FLAGTRUE,false,"AAPL,aux-power-connected",NULL,DWRVAL((uint32_t)1)},
//{FLAGTRUE,false,"AAPL,aux-power-connected", NULL,DWRVAL((uint32_t)1)},
//{FLAGTRUE,false,"AAPL,backlight-control",NULL,DWRVAL((uint32_t)0)},
{FLAGTRUE,false,"ATY,bin_image",get_binimage_val,NULVAL},
{FLAGTRUE,false,"ATY,Copyright",NULL,STRVAL("Copyright AMD Inc. All Rights Reserved. 2005-2010")},
{FLAGTRUE,false,"ATY,Copyright",NULL,STRVAL("Copyright AMD Inc. All Rights Reserved. 2005-2010") },
{FLAGTRUE,false,"ATY,Card#",get_romrevision_val,NULVAL},
{FLAGTRUE,false,"ATY,VendorID",NULL,WRDVAL((uint16_t)0x1002)},
{FLAGTRUE,false,"ATY,DeviceID",get_deviceid_val,NULVAL},
//{FLAGTRUE,false,"ATY,MCLK",get_mclk_val,NULVAL},
//{FLAGTRUE,false,"ATY,SCLK",get_sclk_val,NULVAL},
//{FLAGTRUE,false,"ATY,RefCLK",get_refclk_val,DWRVAL((uint32_t)0x0a8c)},
//{FLAGTRUE,false,"ATY,PlatformInfo",get_platforminfo_val,NULVAL},
{FLAGTRUE,false,"name",get_nameparent_val,NULVAL},
{FLAGTRUE,false,"device_type",get_nameparent_val,NULVAL},
{FLAGTRUE,false,"model",get_model_val,STRVAL("ATI Radeon")},
//{FLAGTRUE,false,"VRAM,totalsize",get_vramtotalsize_val,NULVAL},
{FLAGTRUE,false,NULL,NULL,NULVAL}
};
bool get_bootdisplay_val(value_t *val)
{
static uint32_t v = 0;
if (v)
return false;
if (!card->posted)
return false;
v = 1;
val->type = kCst;
val->size = 4;
val->data = (uint8_t *)&v;
return true;
}
val->type = aty_name.type;
val->size = aty_name.size;
val->data = aty_name.data;
return true;
}
val->type = aty_nameparent.type;
val->size = aty_nameparent.size;
val->data = aty_nameparent.data;
return true;
}
{
if (!card->info->model_name)
return false;
val->type = kStr;
val->size = strlen(card->info->model_name) + 1;
val->data = (uint8_t *)card->info->model_name;
return true;
}
bool get_conntype_val(value_t *val)
{
/*
Connector types:
0x4 : DisplayPort
0x400: DL DVI-I
0x800: HDMI
*/
//Connector types:
//0x4 : DisplayPort
//0x400: DL DVI-I
//0x800: HDMI
return false;
}
{
static int idx = -1;
static uint64_t memsize;
idx++;
memsize = ((uint64_t)card->vram_size << 32);
if (idx == 0)
memsize = memsize | (uint64_t)card->vram_size;
val->type = kCst;
val->size = 8;
val->data = (uint8_t *)&memsize;
return true;
}
{
if (!card->rom)
return false;
val->type = kPtr;
val->size = card->rom_size;
val->data = card->rom;
return true;
}
uint8_t *rev;
if (!card->rom)
return false;
rev = card->rom + *(uint8_t *)(card->rom + OFFSET_TO_GET_ATOMBIOS_STRINGS_START);
val->type = kPtr;
val->size = strlen((char *)rev);
val->data = malloc(val->size);
if (!val->data)
return false;
memcpy(val->data, rev, val->size);
return true;
}
val->type = kCst;
val->size = 2;
val->data = (uint8_t *)&card->pci_dev->device_id;
return true;
}
val->data = malloc(0x80);
if (!val->data)
return false;
bzero(val->data, 0x80);
val->type= kPtr;
val->size= 0x80;
val->data[0]= 1;
return true;
}
val->type = kCst;
val->size = 4;
val->data = (uint8_t *)&card->vram_size;
return true;
}
{
if (val->type == kPtr)
free(val->data);
bzero(val, sizeof(value_t));
}
{
value_t *val = malloc(sizeof(value_t));
int i, pnum;
for (i = 0; devprop_list[i].name != NULL; i++)
{
if ((devprop_list[i].flags == FLAGTRUE) || (devprop_list[i].flags | card->flags))
{
if (devprop_list[i].get_value && devprop_list[i].get_value(val))
{
devprop_add_value(card->device, devprop_list[i].name, val->data, val->size);
free_val(val);
if (devprop_list[i].all_ports)
{
for (pnum = 1; pnum < card->ports; pnum++)
else
{
if (devprop_list[i].default_val.type != kNul)
devprop_add_value(card->device, devprop_list[i].name,
devprop_list[i].default_val.type == kCst ?
(uint8_t *)&(devprop_list[i].default_val.data) : devprop_list[i].default_val.data,
{
devprop_add_value(card->device, devprop_list[i].name,
devprop_list[i].default_val.type == kCst ?
(uint8_t *)&(devprop_list[i].default_val.data) : devprop_list[i].default_val.data,
devprop_list[i].default_val.size);
}
if (devprop_list[i].all_ports)
{
for (pnum = 1; pnum < card->ports; pnum++)
if (devprop_list[i].default_val.type != kNul)
{
devprop_list[i].name[1] = 0x30 + pnum; // convert to ascii
devprop_add_value(card->device, devprop_list[i].name,
devprop_list[i].default_val.type == kCst ?
(uint8_t *)&(devprop_list[i].default_val.data) : devprop_list[i].default_val.data,
devprop_add_value(card->device, devprop_list[i].name,
devprop_list[i].default_val.type == kCst ?
(uint8_t *)&(devprop_list[i].default_val.data) : devprop_list[i].default_val.data,
devprop_list[i].default_val.size);
}
}
devprop_list[i].name[1] = 0x30; // write back our "@0," for a next possible card
}
}
}
}
free(val);
}
bool validate_rom(option_rom_header_t *rom_header, pci_dt_t *pci_dev)
{
option_rom_pci_header_t *rom_pci_header;
if (rom_header->signature != 0xaa55)
return false;
rom_pci_header = (option_rom_pci_header_t *)((uint8_t *)rom_header + rom_header->pci_header_offset);
if (rom_pci_header->signature != 0x52494350)
return false;
if (rom_pci_header->vendor_id != pci_dev->vendor_id || rom_pci_header->device_id != pci_dev->device_id)
return false;
return true;
}
bool load_vbios_file(const char *key, uint16_t vendor_id, uint16_t device_id, uint32_t subsys_id)
{
intfd;
int fd;
char file_name[24];
bool do_load = false;
getBoolForKey(key, &do_load, &bootInfo->chameleonConfig);
if (!do_load)
return false;
sprintf(file_name, "/Extra/%04x_%04x_%08x.rom", vendor_id, device_id, subsys_id);
if ((fd = open_bvdev("bt(0,0)", file_name, 0)) < 0)
return false;
card->rom_size = file_size(fd);
card->rom = malloc(card->rom_size);
if (!card->rom)
return false;
read(fd, (char *)card->rom, card->rom_size);
if (!validate_rom((option_rom_header_t *)card->rom, card->pci_dev))
card->rom = 0;
return false;
}
card->rom_size = ((option_rom_header_t *)card->rom)->rom_size * 512;
close(fd);
return true;
}
void get_vram_size(void)
{
chip_family_t chip_family = card->info->chip_family;
card->vram_size = 0;
if (chip_family >= CHIP_FAMILY_CEDAR)
/* size in MB on evergreen */
/* XXX watch for overflow!!! */
// size in MB on evergreen
// XXX watch for overflow!!!
card->vram_size = RegRead32(R600_CONFIG_MEMSIZE) * 1024 * 1024;
else
if (chip_family >= CHIP_FAMILY_R600)
bool read_vbios(bool from_pci)
{
option_rom_header_t *rom_addr;
if (from_pci)
{
rom_addr = (option_rom_header_t *)(pci_config_read32(card->pci_dev->dev.addr, PCI_ROM_ADDRESS) & ~0x7ff);
}
else
rom_addr = (option_rom_header_t *)0xc0000;
if (!validate_rom(rom_addr, card->pci_dev))
return false;
card->rom_size = rom_addr->rom_size * 512;
if (!card->rom_size)
return false;
card->rom = malloc(card->rom_size);
if (!card->rom)
return false;
memcpy(card->rom, (void *)rom_addr, card->rom_size);
return true;
}
{
bool ret = false;
chip_family_t chip_family = card->info->chip_family;
if (chip_family >= CHIP_FAMILY_RV770)
{
uint32_t viph_control= RegRead32(RADEON_VIPH_CONTROL);
uint32_t bus_cntl= RegRead32(RADEON_BUS_CNTL);
uint32_t d1vga_control= RegRead32(AVIVO_D1VGA_CONTROL);
uint32_t d2vga_control= RegRead32(AVIVO_D2VGA_CONTROL);
uint32_t vga_render_control= RegRead32(AVIVO_VGA_RENDER_CONTROL);
uint32_t vga_render_control = RegRead32(AVIVO_VGA_RENDER_CONTROL);
uint32_t rom_cntl= RegRead32(R600_ROM_CNTL);
uint32_t cg_spll_func_cntl= 0;
uint32_t cg_spll_status;
/* disable VIP */
// disable VIP
RegWrite32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
/* enable the rom */
// enable the rom
RegWrite32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
/* Disable VGA mode */
// Disable VGA mode
RegWrite32(AVIVO_D1VGA_CONTROL, (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
RegWrite32(AVIVO_D2VGA_CONTROL, (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
RegWrite32(AVIVO_VGA_RENDER_CONTROL, (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
if (chip_family == CHIP_FAMILY_RV730)
{
cg_spll_func_cntl = RegRead32(R600_CG_SPLL_FUNC_CNTL);
/* enable bypass mode */
// enable bypass mode
RegWrite32(R600_CG_SPLL_FUNC_CNTL, (cg_spll_func_cntl | R600_SPLL_BYPASS_EN));
/* wait for SPLL_CHG_STATUS to change to 1 */
// wait for SPLL_CHG_STATUS to change to 1
cg_spll_status = 0;
while (!(cg_spll_status & R600_SPLL_CHG_STATUS))
cg_spll_status = RegRead32(R600_CG_SPLL_STATUS);
RegWrite32(R600_ROM_CNTL, (rom_cntl & ~R600_SCK_OVERWRITE));
}
else
RegWrite32(R600_ROM_CNTL, (rom_cntl | R600_SCK_OVERWRITE));
ret = read_vbios(true);
/* restore regs */
// restore regs
if (chip_family == CHIP_FAMILY_RV730)
{
RegWrite32(R600_CG_SPLL_FUNC_CNTL, cg_spll_func_cntl);
/* wait for SPLL_CHG_STATUS to change to 1 */
// wait for SPLL_CHG_STATUS to change to 1
cg_spll_status = 0;
while (!(cg_spll_status & R600_SPLL_CHG_STATUS))
cg_spll_status = RegRead32(R600_CG_SPLL_STATUS);
uint32_t viph_control= RegRead32(RADEON_VIPH_CONTROL);
uint32_t bus_cntl= RegRead32(RADEON_BUS_CNTL);
uint32_t d1vga_control= RegRead32(AVIVO_D1VGA_CONTROL);
uint32_t d2vga_control = RegRead32(AVIVO_D2VGA_CONTROL);
uint32_t d2vga_control= RegRead32(AVIVO_D2VGA_CONTROL);
uint32_t vga_render_control= RegRead32(AVIVO_VGA_RENDER_CONTROL);
uint32_t rom_cntl= RegRead32(R600_ROM_CNTL);
uint32_t general_pwrmgt= RegRead32(R600_GENERAL_PWRMGT);
uint32_t low_vid_lower_gpio_cntl= RegRead32(R600_LOW_VID_LOWER_GPIO_CNTL);
uint32_t medium_vid_lower_gpio_cntl= RegRead32(R600_MEDIUM_VID_LOWER_GPIO_CNTL);
uint32_t medium_vid_lower_gpio_cntl = RegRead32(R600_MEDIUM_VID_LOWER_GPIO_CNTL);
uint32_t high_vid_lower_gpio_cntl= RegRead32(R600_HIGH_VID_LOWER_GPIO_CNTL);
uint32_t ctxsw_vid_lower_gpio_cntl= RegRead32(R600_CTXSW_VID_LOWER_GPIO_CNTL);
uint32_t lower_gpio_enable= RegRead32(R600_LOWER_GPIO_ENABLE);
/* disable VIP */
// disable VIP
RegWrite32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
/* enable the rom */
// enable the rom
RegWrite32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
/* Disable VGA mode */
// Disable VGA mode
RegWrite32(AVIVO_D1VGA_CONTROL, (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
RegWrite32(AVIVO_D2VGA_CONTROL, (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
RegWrite32(AVIVO_VGA_RENDER_CONTROL, (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
RegWrite32(R600_HIGH_VID_LOWER_GPIO_CNTL, (high_vid_lower_gpio_cntl & ~0x400));
RegWrite32(R600_CTXSW_VID_LOWER_GPIO_CNTL, (ctxsw_vid_lower_gpio_cntl & ~0x400));
RegWrite32(R600_LOWER_GPIO_ENABLE, (lower_gpio_enable | 0x400));
ret = read_vbios(true);
/* restore regs */
// restore regs
RegWrite32(RADEON_VIPH_CONTROL, viph_control);
RegWrite32(RADEON_BUS_CNTL, bus_cntl);
RegWrite32(AVIVO_D1VGA_CONTROL, d1vga_control);
RegWrite32(R600_HIGH_VID_LOWER_GPIO_CNTL, high_vid_lower_gpio_cntl);
RegWrite32(R600_CTXSW_VID_LOWER_GPIO_CNTL, ctxsw_vid_lower_gpio_cntl);
RegWrite32(R600_LOWER_GPIO_ENABLE, lower_gpio_enable);
}
return ret;
bool radeon_card_posted(void)
{
uint32_t reg;
/* first check CRTCs */
// first check CRTCs
reg = RegRead32(RADEON_CRTC_GEN_CNTL) | RegRead32(RADEON_CRTC2_GEN_CNTL);
if (reg & RADEON_CRTC_EN)
return true;
/* then check MEM_SIZE, in case something turned the crtcs off */
// then check MEM_SIZE, in case something turned the crtcs off
reg = RegRead32(R600_CONFIG_MEMSIZE);
if (reg)
return true;
return false;
}
#if 0
bool devprop_add_pci_config_space(void)
{
int offset;
uint8_t *config_space = malloc(0x100);
if (!config_space)
return false;
for (offset = 0; offset < 0x100; offset += 4)
config_space[offset / 4] = pci_config_read32(card->pci_dev->dev.addr, offset);
devprop_add_value(card->device, "ATY,PCIConfigSpace", config_space, 0x100);
free(config_space);
return true;
}
#endif
static bool init_card(pci_dt_t *pci_dev)
{
char name[24];
char name_parent[24];
int i;
bool add_vbios = true;
booladd_vbios = true;
charname[24];
charname_parent[24];
inti;
intn_ports = 0;
card = malloc(sizeof(card_t));
if (!card)
return false;
bzero(card, sizeof(card_t));
card->pci_dev = pci_dev;
for (i = 0; radeon_cards[i].device_id ; i++)
{
if (radeon_cards[i].device_id == pci_dev->device_id)
{
card->info = &radeon_cards[i];
if ((radeon_cards[i].subsys_id == 0x00000000) ||
if ((radeon_cards[i].subsys_id == 0x00000000) ||
(radeon_cards[i].subsys_id == pci_dev->subsys_id.subsys_id))
break;
}
}
if (!card->info->device_id || !card->info->cfg_name)
{
printf("Unsupported card!\n");
return false;
}
card->fb= (uint8_t *)(pci_config_read32(pci_dev->dev.addr, PCI_BASE_ADDRESS_0) & ~0x0f);
card->mmio= (uint8_t *)(pci_config_read32(pci_dev->dev.addr, PCI_BASE_ADDRESS_2) & ~0x0f);
card->io= (uint8_t *)(pci_config_read32(pci_dev->dev.addr, PCI_BASE_ADDRESS_4) & ~0x03);
verbose("Framebuffer @0x%08X MMIO @0x%08X I/O Port @0x%08X ROM Addr @0x%08X\n",
verbose("Framebuffer @0x%08X MMIO @0x%08XI/O Port @0x%08X ROM Addr @0x%08X\n",
card->fb, card->mmio, card->io, pci_config_read32(pci_dev->dev.addr, PCI_ROM_ADDRESS));
card->posted= radeon_card_posted();
card->posted = radeon_card_posted();
verbose("ATI card %s, ", card->posted ? "POSTed" : "non-POSTed");
get_vram_size();
getBoolForKey(kATYbinimage, &add_vbios, &bootInfo->chameleonConfig);
if (add_vbios)
{
if (!load_vbios_file(kUseAtiROM, pci_dev->vendor_id, pci_dev->device_id, pci_dev->subsys_id.subsys_id))
{
verbose("reading VBIOS from %s", card->posted ? "legacy space" : "PCI ROM");
read_disabled_vbios();
verbose("\n");
}
card->ports = 2; // default
if (card->info->chip_family >= CHIP_FAMILY_CEDAR)
{
card->flags |= EVERGREEN;
card->ports = 3;
}
atN = 0;
//atN = 0;
card->cfg_name = getStringForKey(kAtiConfig, &bootInfo->chameleonConfig);
if (!card->cfg_name)
{
if (strcmp(card->cfg_name, card_configs[i].name) == 0)
card->ports = card_configs[i].ports;
}
if (card->info->chip_family >= CHIP_FAMILY_CEDAR)
{
card->flags |= EVERGREEN;
card->ports = 3; //Azi: not sure of the usefulness ??
}
getIntForKey(kAtiPorts, &n_ports, &bootInfo->bootConfig);
if (n_ports > 0)
card->ports = n_ports;
sprintf(name, "ATY,%s", card->cfg_name);
aty_name.type = kStr;
aty_name.size = strlen(name) + 1;
aty_name.data = (uint8_t *)name;
sprintf(name_parent, "ATY,%sParent", card->cfg_name);
aty_nameparent.type = kStr;
aty_nameparent.size = strlen(name_parent) + 1;
aty_nameparent.data = (uint8_t *)name_parent;
return true;
}
bool setup_ati_devprop(pci_dt_t *ati_dev)
{
char *devicepath;
if (!init_card(ati_dev))
return false;
/* ------------------------------------------------- */
/* Find a better way to do this (in device_inject.c) */
// -------------------------------------------------
// Find a better way to do this (in device_inject.c)
if (!string)
string = devprop_create_string();
devicepath = get_pci_dev_path(ati_dev);
card->device = devprop_add_device(string, devicepath);
if (!card->device)
return false;
/* ------------------------------------------------- */
// -------------------------------------------------
#if 0
uint64_t fb= (uint32_t)card->fb;
uint64_t mmio= (uint32_t)card->mmio;
devprop_add_value(card->device, "ATY,RegisterSpaceOffset", &mmio, 8);
devprop_add_value(card->device, "ATY,IOSpaceOffset", &io, 8);
#endif
devprop_add_list(ati_devprop_list);
/* ------------------------------------------------- */
/* Find a better way to do this (in device_inject.c) */
stringdata = malloc(string->length);
// -------------------------------------------------
// Find a better way to do this (in device_inject.c)
//Azi: XXX tried to fix a malloc error in vain; this is related to XCode 4 compilation!
stringdata = malloc(sizeof(uint8_t) * string->length);
memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
stringlength = string->length;
/* ------------------------------------------------- */
verbose("ATI %s %s %dMB (%s) [%04x:%04x] (subsys [%04x:%04x]):: %s\n",
chip_family_name[card->info->chip_family], card->info->model_name,
(uint32_t)(card->vram_size / (1024 * 1024)), card->cfg_name,
// -------------------------------------------------
verbose("ATI %s %s %dMB (%s) [%04x:%04x] (subsys [%04x:%04x]):: %s\n",
chip_family_name[card->info->chip_family], card->info->model_name,
(uint32_t)(card->vram_size / (1024 * 1024)), card->cfg_name,
ati_dev->vendor_id, ati_dev->device_id,
ati_dev->subsys_id.subsys.vendor_id, ati_dev->subsys_id.subsys.device_id,
ati_dev->subsys_id.subsys.vendor_id, ati_dev->subsys_id.subsys.device_id,
devicepath);
free(card);
return true;
}
branches/azimutz/trunkAutoResolution/i386/libsaio/cpu.c
3030
3131
3232
33
33
3434
3535
3636
......
6767
6868
6969
70
70
7171
7272
7373
......
8383
8484
8585
86
8687
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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
87195
88196
89197
......
101209
102210
103211
104
212
105213
106214
107
215
108216
109217
110218
111219
112220
113
221
114222
115
223
224
225
226
227
116228
117229
230
231
118232
119233
120234
121235
122236
123237
124
125
238
239
126240
127241
128242
......
136250
137251
138252
139
253
140254
141255
142256
143
257
258
144259
145260
146261
147
262
263
264
265
266
267
268
269
148270
149271
150272
......
171293
172294
173295
174
175
176
177
178
179
296
297
298
299
300
301
180302
181303
182304
......
208330
209331
210332
211
333
212334
213335
214336
215
216
337
338
217339
218340
219341
......
227349
228350
229351
230
231
232
352
353
354
233355
234
235
236
356
357
358
237359
238
239
240
241
242
243
244
360
361
362
363
364
365
366
245367
246368
247
369
248370
249371
250
372
251373
252374
253375
254376
255377
256378
257
379
258380
259381
260382
......
270392
271393
272394
273
395
274396
275
397
276398
277399
278400
......
286408
287409
288410
289
411
290412
291413
292414
293415
294416
295
296
417
418
297419
298
420
299421
300
301
422
423
302424
303425
304426
305
427
306428
307429
308430
309431
310432
311
433
312434
313435
314436
......
329451
330452
331453
332
333
334
335
336
337
338
339
340
341
342
343
344
345
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
346486
347
348
349
350
351
352
353
354
355
356
357
358
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
359503
360
361
362
363
364
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
365532
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
385552
386
553
387554
388555
unsigned long pollCount;
uint64_t retval = 0;
int i;
/* Time how many TSC ticks elapse in 30 msec using the 8254 PIT
* counter 2. We run this loop 3 times to make sure the cache
* is hot and we take the minimum delta from all of the runs.
* Hz so we need to convert our milliseconds to seconds. Since we're
* dividing by the milliseconds, we simply multiply by 1000.
*/
/* Unlike linux, we're not limited to 32-bit, but we do need to take care
* that we're going to multiply by 1000 first so we do need at least some
* arithmetic headroom. For now, 32-bit should be enough.
return retval;
}
#if 0
/*
* DFE: Measures the Max Performance Frequency in Hz (64-bit)
*/
static uint64_t measure_mperf_frequency(void)
{
uint64_t mperfStart;
uint64_t mperfEnd;
uint64_t mperfDelta = 0xffffffffffffffffULL;
unsigned long pollCount;
uint64_t retval = 0;
int i;
/* Time how many MPERF ticks elapse in 30 msec using the 8254 PIT
* counter 2. We run this loop 3 times to make sure the cache
* is hot and we take the minimum delta from all of the runs.
* That is to say that we're biased towards measuring the minimum
* number of MPERF ticks that occur while waiting for the timer to
* expire.
*/
for(i = 0; i < 10; ++i)
{
enable_PIT2();
set_PIT2_mode0(CALIBRATE_LATCH);
mperfStart = rdmsr64(MSR_AMD_MPERF);
pollCount = poll_PIT2_gate();
mperfEnd = rdmsr64(MSR_AMD_MPERF);
/* The poll loop must have run at least a few times for accuracy */
if(pollCount <= 1)
continue;
/* The MPERF must increment at LEAST once every millisecond. We
* should have waited exactly 30 msec so the MPERF delta should
* be >= 30. Anything less and the processor is way too slow.
*/
if((mperfEnd - mperfStart) <= CALIBRATE_TIME_MSEC)
continue;
// tscDelta = MIN(tscDelta, (tscEnd - tscStart))
if( (mperfEnd - mperfStart) < mperfDelta )
mperfDelta = mperfEnd - mperfStart;
}
/* mperfDelta is now the least number of MPERF ticks the processor made in
* a timespan of 0.03 s (e.g. 30 milliseconds)
*/
if(mperfDelta > (1ULL<<32))
retval = 0;
else
{
retval = mperfDelta * 1000 / 30;
}
disable_PIT2();
return retval;
}
#endif
/*
* Measures the Actual Performance Frequency in Hz (64-bit)
*/
static uint64_t measure_aperf_frequency(void)
{
uint64_t aperfStart;
uint64_t aperfEnd;
uint64_t aperfDelta = 0xffffffffffffffffULL;
unsigned long pollCount;
uint64_t retval = 0;
int i;
/* Time how many APERF ticks elapse in 30 msec using the 8254 PIT
* counter 2. We run this loop 3 times to make sure the cache
* is hot and we take the minimum delta from all of the runs.
* That is to say that we're biased towards measuring the minimum
* number of APERF ticks that occur while waiting for the timer to
* expire.
*/
for(i = 0; i < 10; ++i)
{
enable_PIT2();
set_PIT2_mode0(CALIBRATE_LATCH);
aperfStart = rdmsr64(MSR_AMD_APERF);
pollCount = poll_PIT2_gate();
aperfEnd = rdmsr64(MSR_AMD_APERF);
/* The poll loop must have run at least a few times for accuracy */
if(pollCount <= 1)
continue;
/* The TSC must increment at LEAST once every millisecond. We
* should have waited exactly 30 msec so the APERF delta should
* be >= 30. Anything less and the processor is way too slow.
*/
if((aperfEnd - aperfStart) <= CALIBRATE_TIME_MSEC)
continue;
// tscDelta = MIN(tscDelta, (tscEnd - tscStart))
if( (aperfEnd - aperfStart) < aperfDelta )
aperfDelta = aperfEnd - aperfStart;
}
/* mperfDelta is now the least number of MPERF ticks the processor made in
* a timespan of 0.03 s (e.g. 30 milliseconds)
*/
if(aperfDelta > (1ULL<<32))
retval = 0;
else
{
retval = aperfDelta * 1000 / 30;
}
disable_PIT2();
return retval;
}
/*
* Calculates the FSB and CPU frequencies using specific MSRs for each CPU
* - multi. is read from a specific MSR. In the case of Intel, there is:
* a max multi. (used to calculate the FSB freq.),
int len, myfsb;
uint8_t bus_ratio_min;
uint32_t max_ratio, min_ratio;
max_ratio = min_ratio = myfsb = bus_ratio_min = 0;
maxcoef = maxdiv = bus_ratio_max = currcoef = currdiv = 0;
/* get cpuid values */
do_cpuid(0x00000000, p->CPU.CPUID[CPUID_0]);
do_cpuid(0x00000001, p->CPU.CPUID[CPUID_1]);
do_cpuid(0x00000002, p->CPU.CPUID[CPUID_2]);
do_cpuid(0x00000003, p->CPU.CPUID[CPUID_3]);
do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]);
do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]);
do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]);
if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1) {
if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8) {
do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]);
do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
}
else if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1) {
do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
}
#if DEBUG_CPU
{
inti;
printf("CPUID Raw Values:\n");
for (i=0; i<CPUID_MAX; i++) {
printf("%02d: %08x-%08x-%08x-%08x\n", i,
p->CPU.CPUID[i][0], p->CPU.CPUID[i][1],
p->CPU.CPUID[i][2], p->CPU.CPUID[i][3]);
p->CPU.CPUID[i][0], p->CPU.CPUID[i][1],
p->CPU.CPUID[i][2], p->CPU.CPUID[i][3]);
}
}
#endif
p->CPU.Model += (p->CPU.ExtModel << 4);
if (p->CPU.Vendor == 0x756E6547 /* Intel */ &&
if (p->CPU.Vendor == CPUID_VENDOR_INTEL &&
p->CPU.Family == 0x06 &&
p->CPU.Model >= CPUID_MODEL_NEHALEM &&
p->CPU.Model != CPUID_MODEL_ATOM // MSR is *NOT* available on the Intel Atom CPU
){
)
{
msr = rdmsr64(MSR_CORE_THREAD_COUNT);// Undocumented MSR in Nehalem and newer CPUs
p->CPU.NoCores= bitfield((uint32_t)msr, 31, 16);// Using undocumented MSR to get actual values
p->CPU.NoThreads= bitfield((uint32_t)msr, 15, 0);// Using undocumented MSR to get actual values
} else {
}
else if (p->CPU.Vendor == CPUID_VENDOR_AMD)
{
p->CPU.NoThreads= bitfield(p->CPU.CPUID[CPUID_1][1], 23, 16);
p->CPU.NoCores= bitfield(p->CPU.CPUID[CPUID_88][2], 7, 0) + 1;
}
else
{
p->CPU.NoThreads= bitfield(p->CPU.CPUID[CPUID_1][1], 23, 16);// Use previous method for Cores and Threads
p->CPU.NoCores= bitfield(p->CPU.CPUID[CPUID_4][0], 31, 26) + 1;
}
strlcpy(p->CPU.BrandString,s, sizeof(p->CPU.BrandString));
if (!strncmp(p->CPU.BrandString, CPU_STRING_UNKNOWN, MIN(sizeof(p->CPU.BrandString), strlen(CPU_STRING_UNKNOWN) + 1))) {
/*
* This string means we have a firmware-programmable brand string,
* and the firmware couldn't figure out what sort of CPU we have.
*/
p->CPU.BrandString[0] = '\0';
}
/*
* This string means we have a firmware-programmable brand string,
* and the firmware couldn't figure out what sort of CPU we have.
*/
p->CPU.BrandString[0] = '\0';
}
}
/* setup features */
if (p->CPU.NoThreads > p->CPU.NoCores) {
p->CPU.Features |= CPU_FEATURE_HTT;
}
tscFrequency = measure_tsc_frequency();
fsbFrequency = 0;
cpuFrequency = 0;
if ((p->CPU.Vendor == 0x756E6547 /* Intel */) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) {
if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) {
int intelCPU = p->CPU.Model;
if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)) {
/* Nehalem CPU model */
p->CPU.Model == CPU_MODEL_SANDY ||
p->CPU.Model == CPU_MODEL_SANDY_XEON)) {
msr = rdmsr64(MSR_PLATFORM_INFO);
DBG("msr(%d): platform_info %08x\n", __LINE__, msr & 0xffffffff);
bus_ratio_max = (msr >> 8) & 0xff;
bus_ratio_min = (msr >> 40) & 0xff; //valv: not sure about this one (Remarq.1)
DBG("msr(%d): platform_info %08x\n", __LINE__, bitfield(msr, 31, 0));
bus_ratio_max = bitfield(msr, 14, 8);
bus_ratio_min = bitfield(msr, 46, 40); //valv: not sure about this one (Remarq.1)
msr = rdmsr64(MSR_FLEX_RATIO);
DBG("msr(%d): flex_ratio %08x\n", __LINE__, msr & 0xffffffff);
if ((msr >> 16) & 0x01) {
flex_ratio = (msr >> 8) & 0xff;
DBG("msr(%d): flex_ratio %08x\n", __LINE__, bitfield(msr, 31, 0));
if (bitfield(msr, 16, 16)) {
flex_ratio = bitfield(msr, 14, 8);
/* bcc9: at least on the gigabyte h67ma-ud2h,
where the cpu multipler can't be changed to
allow overclocking, the flex_ratio msr has unexpected (to OSX)
contents. These contents cause mach_kernel to
fail to compute the bus ratio correctly, instead
causing the system to crash since tscGranularity
is inadvertently set to 0.
*/
where the cpu multipler can't be changed to
allow overclocking, the flex_ratio msr has unexpected (to OSX)
contents. These contents cause mach_kernel to
fail to compute the bus ratio correctly, instead
causing the system to crash since tscGranularity
is inadvertently set to 0.
*/
if (flex_ratio == 0) {
/* Clear bit 16 (evidently the
presence bit) */
presence bit) */
wrmsr64(MSR_FLEX_RATIO, (msr & 0xFFFFFFFFFFFEFFFFULL));
msr = rdmsr64(MSR_FLEX_RATIO);
verbose("Unusable flex ratio detected. Patched MSR now %08x\n", msr & 0xffffffff);
verbose("Unusable flex ratio detected. Patched MSR now %08x\n", bitfield(msr, 31, 0));
} else {
if (bus_ratio_max > flex_ratio) {
bus_ratio_max = flex_ratio;
}
}
}
if (bus_ratio_max) {
fsbFrequency = (tscFrequency / bus_ratio_max);
}
max_ratio = atoi(newratio);
max_ratio = (max_ratio * 10);
if (len >= 3) max_ratio = (max_ratio + 5);
verbose("Bus-Ratio: min=%d, max=%s\n", bus_ratio_min, newratio);
// extreme overclockers may love 320 ;)
if ((max_ratio >= min_ratio) && (max_ratio <= 320)) {
cpuFrequency = (fsbFrequency * max_ratio) / 10;
/*if(bus_ratio_max > 0) bus_ratio = flex_ratio;*/
p->CPU.MaxRatio = max_ratio;
p->CPU.MinRatio = min_ratio;
myfsb = fsbFrequency / 1000000;
verbose("Sticking with [BCLK: %dMhz, Bus-Ratio: %d]\n", myfsb, max_ratio);
currcoef = bus_ratio_max;
} else {
msr = rdmsr64(MSR_IA32_PERF_STATUS);
DBG("msr(%d): ia32_perf_stat 0x%08x\n", __LINE__, msr & 0xffffffff);
currcoef = (msr >> 8) & 0x1f;
DBG("msr(%d): ia32_perf_stat 0x%08x\n", __LINE__, bitfield(msr, 31, 0));
currcoef = bitfield(msr, 12, 8);
/* Non-integer bus ratio for the max-multi*/
maxdiv = (msr >> 46) & 0x01;
maxdiv = bitfield(msr, 46, 46);
/* Non-integer bus ratio for the current-multi (undocumented)*/
currdiv = (msr >> 14) & 0x01;
currdiv = bitfield(msr, 14, 14);
if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0e) || (p->CPU.Family == 0x0f)) // This will always be model >= 3
{
/* On these models, maxcoef defines TSC freq */
maxcoef = (msr >> 40) & 0x1f;
maxcoef = bitfield(msr, 44, 40);
} else {
/* On lower models, currcoef defines TSC freq */
/* XXX */
maxcoef = currcoef;
}
if (maxcoef) {
if (maxdiv) {
fsbFrequency = ((tscFrequency * 2) / ((maxcoef * 2) + 1));
p->CPU.Features |= CPU_FEATURE_MOBILE;
}
}
#if 0
else if((p->CPU.Vendor == 0x68747541 /* AMD */) && (p->CPU.Family == 0x0f)) {
if(p->CPU.ExtFamily == 0x00 /* K8 */) {
msr = rdmsr64(K8_FIDVID_STATUS);
currcoef = (msr & 0x3f) / 2 + 4;
currdiv = (msr & 0x01) * 2;
} else if(p->CPU.ExtFamily >= 0x01 /* K10+ */) {
msr = rdmsr64(K10_COFVID_STATUS);
if(p->CPU.ExtFamily == 0x01 /* K10 */)
currcoef = (msr & 0x3f) + 0x10;
else /* K11+ */
currcoef = (msr & 0x3f) + 0x08;
currdiv = (2 << ((msr >> 6) & 0x07));
}
else if((p->CPU.Vendor == CPUID_VENDOR_AMD) && (p->CPU.Family == 0x0f))
{
switch(p->CPU.ExtFamily)
{
case 0x00: /* K8 */
msr = rdmsr64(K8_FIDVID_STATUS);
maxcoef = bitfield(msr, 21, 16) / 2 + 4;
currcoef = bitfield(msr, 5, 0) / 2 + 4;
break;
case 0x01: /* K10 */
msr = rdmsr64(K10_COFVID_STATUS);
do_cpuid2(0x00000006, 0, p->CPU.CPUID[CPUID_6]);
if(bitfield(p->CPU.CPUID[CPUID_6][2], 0, 0) == 1) // EffFreq: effective frequency interface
{
//uint64_t mperf = measure_mperf_frequency();
uint64_t aperf = measure_aperf_frequency();
cpuFrequency = aperf;
}
// NOTE: tsc runs at the maccoeff (non turbo)
// *not* at the turbo frequency.
maxcoef = bitfield(msr, 54, 49) / 2 + 4;
currcoef = bitfield(msr, 5, 0) + 0x10;
currdiv = 2 << bitfield(msr, 8, 6);
break;
case 0x05: /* K14 */
msr = rdmsr64(K10_COFVID_STATUS);
currcoef = (bitfield(msr, 54, 49) + 0x10) << 2;
currdiv = (bitfield(msr, 8, 4) + 1) << 2;
currdiv += bitfield(msr, 3, 0);
if (currcoef) {
if (currdiv) {
fsbFrequency = ((tscFrequency * currdiv) / currcoef);
DBG("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
} else {
fsbFrequency = (tscFrequency / currcoef);
DBG("%d\n", currcoef);
}
fsbFrequency = (tscFrequency / currcoef);
cpuFrequency = tscFrequency;
}
}
break;
case 0x02: /* K11 */
// not implimented
break;
}
if (maxcoef)
{
if (currdiv)
{
if(!currcoef) currcoef = maxcoef;
if(!cpuFrequency)
fsbFrequency = ((tscFrequency * currdiv) / currcoef);
else
fsbFrequency = ((cpuFrequency * currdiv) / currcoef);
if (!fsbFrequency) {
fsbFrequency = (DEFAULT_FSB * 1000);
cpuFrequency = tscFrequency;
DBG("0 ! using the default value for FSB !\n");
}
DBG("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
} else {
if(!cpuFrequency)
fsbFrequency = (tscFrequency / maxcoef);
else
fsbFrequency = (cpuFrequency / maxcoef);
DBG("%d\n", currcoef);
}
}
else if (currcoef)
{
if (currdiv)
{
fsbFrequency = ((tscFrequency * currdiv) / currcoef);
DBG("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
} else {
fsbFrequency = (tscFrequency / currcoef);
DBG("%d\n", currcoef);
}
}
if(!cpuFrequency) cpuFrequency = tscFrequency;
}
#if 0
if (!fsbFrequency) {
fsbFrequency = (DEFAULT_FSB * 1000);
cpuFrequency = tscFrequency;
DBG("0 ! using the default value for FSB !\n");
}
#endif
p->CPU.MaxCoef = maxcoef;
p->CPU.MaxDiv = maxdiv;
p->CPU.CurrCoef = currcoef;
p->CPU.CurrDiv = currdiv;
p->CPU.TSCFrequency = tscFrequency;
p->CPU.FSBFrequency = fsbFrequency;
p->CPU.CPUFrequency = cpuFrequency;
DBG("CPU: Brand String: %s\n",p->CPU.BrandString);
DBG("CPU: Vendor/Family/ExtFamily: 0x%x/0x%x/0x%x\n",p->CPU.Vendor, p->CPU.Family, p->CPU.ExtFamily);
DBG("CPU: Model/ExtModel/Stepping: 0x%x/0x%x/0x%x\n",p->CPU.Model, p->CPU.ExtModel, p->CPU.Stepping);
DBG("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n",p->CPU.MaxCoef, p->CPU.CurrCoef);
DBG("CPU: MaxDiv/CurrDiv: 0x%x/0x%x\n",p->CPU.MaxDiv, p->CPU.CurrDiv);
DBG("CPU: TSCFreq: %dMHz\n",p->CPU.TSCFrequency / 1000000);
DBG("CPU: FSBFreq: %dMHz\n",p->CPU.FSBFrequency / 1000000);
DBG("CPU: CPUFreq: %dMHz\n",p->CPU.CPUFrequency / 1000000);
DBG("CPU: NoCores/NoThreads: %d/%d\n",p->CPU.NoCores, p->CPU.NoThreads);
DBG("CPU: Features: 0x%08x\n",p->CPU.Features);
p->CPU.MaxCoef = maxcoef;
p->CPU.MaxDiv = maxdiv;
p->CPU.CurrCoef = currcoef;
p->CPU.CurrDiv = currdiv;
p->CPU.TSCFrequency = tscFrequency;
p->CPU.FSBFrequency = fsbFrequency;
p->CPU.CPUFrequency = cpuFrequency;
DBG("CPU: Brand String: %s\n",p->CPU.BrandString);
DBG("CPU: Vendor/Family/ExtFamily: 0x%x/0x%x/0x%x\n",p->CPU.Vendor, p->CPU.Family, p->CPU.ExtFamily);
DBG("CPU: Model/ExtModel/Stepping: 0x%x/0x%x/0x%x\n",p->CPU.Model, p->CPU.ExtModel, p->CPU.Stepping);
DBG("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n",p->CPU.MaxCoef, p->CPU.CurrCoef);
DBG("CPU: MaxDiv/CurrDiv: 0x%x/0x%x\n",p->CPU.MaxDiv, p->CPU.CurrDiv);
DBG("CPU: TSCFreq: %dMHz\n",p->CPU.TSCFrequency / 1000000);
DBG("CPU: FSBFreq: %dMHz\n",p->CPU.FSBFrequency / 1000000);
DBG("CPU: CPUFreq: %dMHz\n",p->CPU.CPUFrequency / 1000000);
DBG("CPU: NoCores/NoThreads: %d/%d\n",p->CPU.NoCores, p->CPU.NoThreads);
DBG("CPU: Features: 0x%08x\n",p->CPU.Features);
#if DEBUG_CPU
pause();
pause();
#endif
}
branches/azimutz/trunkAutoResolution/i386/libsaio/platform.h
1313
1414
1515
16
17
18
19
1620
1721
1822
1923
2024
2125
22
23
24
26
27
28
29
30
2531
2632
2733
extern void scan_platform(void);
extern void dumpPhysAddr(const char * title, void * a, int len);
/* CPUID Vendor */
#define CPUID_VENDOR_INTEL 0x756E6547
#define CPUID_VENDOR_AMD 0x68747541
/* CPUID index into cpuid_raw */
#define CPUID_00
#define CPUID_11
#define CPUID_22
#define CPUID_33
#define CPUID_44
#define CPUID_805
#define CPUID_816
#define CPUID_MAX7
#define CPUID_65
#define CPUID_806
#define CPUID_817
#define CPUID_888
#define CPUID_MAX9
#define CPU_MODEL_YONAH0x0E// Sossaman, Yonah
#define CPU_MODEL_MEROM0x0F// Allendale, Conroe, Kentsfield, Woodcrest, Clovertown, Tigerton, Merom
branches/azimutz/trunkAutoResolution/i386/libsaio/cpu.h
1010
1111
1212
13
13
1414
1515
1616
1717
1818
19
19
2020
2121
2222
......
2828
2929
3030
31
32
33
3134
3235
3336
extern void scan_cpu(PlatformInfo_t *);
#define bit(n)(1UL << (n))
#define bit(n)(1ULL << (n))
#define bitmask(h,l)((bit(h)|(bit(h)-1)) & ~(bit(l)-1))
#define bitfield(x,h,l)(((x) & bitmask(h,l)) >> l)
#define CPU_STRING_UNKNOWN"Unknown CPU Type"
#defineMSR_IA32_PERF_STATUS0x198
#defineMSR_IA32_PERF_STATUS0x00000198
#define MSR_IA32_PERF_CONTROL0x199
#define MSR_IA32_EXT_CONFIG0x00EE
#define MSR_FLEX_RATIO0x194
#define K8_FIDVID_STATUS0xC0010042
#define K10_COFVID_STATUS0xC0010071
#define MSR_AMD_MPERF 0x000000E7
#define MSR_AMD_APERF 0x000000E8
#define DEFAULT_FSB100000 /* for now, hardcoding 100MHz for old CPUs */
// DFE: This constant comes from older xnu:
branches/azimutz/trunkAutoResolution/i386/libsaio/stringTable.c
503503
504504
505505
506
506
507507
508508
509509
......
646646
647647
648648
649
649650
650
651651
652652
653
653654
654
655655
656656
657657
// NOTE: Values are defined by apple as being in com.apple.Boot.plist
// kHelperRootUUIDKey, kKernelArchKey, kMKextCacheKey, kKernelCacheKey, kKernelNameKey, kKernelFlagsKey
if (ret && (strcmp(key, kKernelNameKey) == 0) && (strcmp(overrideVal, "mach_kernel") == 0))
if (ret && (strcmp(key, kKernelNameKey) == 0) && (overrideSize == 0))
override = false;
if (ret && (strcmp(key, kKernelFlagsKey) == 0) && (overrideSize == 0))
{
char *dirspec[] = {
"rd(0,0)/Extra/org.chameleon.Boot.plist",
"/Extra/org.chameleon.Boot.plist",
"bt(0,0)/Extra/org.chameleon.Boot.plist",
"/Extra/org.chameleon.Boot.plist",
"rd(0,0)/Extra/com.apple.Boot.plist", /* DEPRECIATED */
"/Extra/com.apple.Boot.plist", /* DEPRECIATED */
"bt(0,0)/Extra/com.apple.Boot.plist", /* DEPRECIATED */
"/Extra/com.apple.Boot.plist" /* DEPRECIATED */
};
int i, fd, count, ret=-1;
branches/azimutz/trunkAutoResolution/i386/boot0/boot0.s
315315
316316
317317
318
319
320
321
322
323
324
325318
326319
327320
328321
329322
330
331
332323
333324
334325
335
336
337
338
339
340
341
342326
343327
344328
345329
346330
347
348331
349332
350333
jne .Pass2
.Pass1:
%if CONFIG_BOOT0_HFSFIRST
cmp BYTE [si + part.type], kPartTypeHFS; In pass 1 we're going to find a HFS+ partition
; equipped with boot1h in its boot record
; regardless if it's active or not.
jne .continue
movdh, 1 ; Argument for loadBootSector to check HFS+ partition signature.
%else
cmp BYTE [si + part.bootid], kPartActive; In pass 1 we are walking on the standard path
; by trying to hop on the active partition.
jne .continue
xor dh, dh ; Argument for loadBootSector to skip HFS+ partition
; signature check.
%endif
jmp .tryToBoot
.Pass2:
%if CONFIG_BOOT0_HFSFIRST
cmp BYTE [si + part.bootid], kPartActive; In pass 2 we are walking on the standard path
; by trying to hop on the active partition.
jne .continue
xordh, dh ; Argument for loadBootSector to skip HFS+ partition
; signature check.
%else
cmp BYTE [si + part.type], kPartTypeHFS; In pass 2 we're going to find a HFS+ partition
; equipped with boot1h in its boot record
; regardless if it's active or not.
jne .continue
mov dh, 1 ; Argument for loadBootSector to check HFS+ partition signature.
%endif
DebugChar('*')
branches/azimutz/trunkAutoResolution/i386/boot0/boot0hfs.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
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
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
; Copyright (c) 1999-2003 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@
;
; Boot Loader: boot0
;
; A small boot sector program written in x86 assembly whose only
; responsibility is to locate the active partition, load the
; partition booter into memory, and jump to the booter's entry point.
; It leaves the boot drive in DL and a pointer to the partition entry in SI.
;
; This boot loader must be placed in the Master Boot Record.
;
; In order to coexist with a fdisk partition table (64 bytes), and
; leave room for a two byte signature (0xAA55) in the end, boot0 is
; restricted to 446 bytes (512 - 64 - 2). If boot0 did not have to
; live in the MBR, then we would have 510 bytes to work with.
;
; boot0 is always loaded by the BIOS or another booter to 0:7C00h.
;
; This code is written for the NASM assembler.
; nasm boot0.s -o boot0
;
; This version of boot0 implements hybrid GUID/MBR partition scheme support
;
;
; Turbo added EFI System Partition boot support
;
; Added KillerJK's switchPass2 modifications
;
;
; Set to 1 to enable obscure debug messages.
;
DEBUGEQU CONFIG_BOOT0_DEBUG
;
; Set to 1 to enable verbose mode
;
VERBOSEEQU CONFIG_BOOT0_VERBOSE
;
; Various constants.
;
kBoot0SegmentEQU 0x0000
kBoot0StackEQU 0xFFF0; boot0 stack pointer
kBoot0LoadAddrEQU 0x7C00; boot0 load address
kBoot0RelocAddrEQU 0xE000; boot0 relocated address
kMBRBufferEQU 0x1000; MBR buffer address
kLBA1BufferEQU 0x1200; LBA1 - GPT Partition Table Header buffer address
kGPTABufferEQU 0x1400; GUID Partition Entry Array buffer address
kPartTableOffsetEQU 0x1be
kMBRPartTableEQU kMBRBuffer + kPartTableOffset
kSectorBytesEQU 512; sector size in bytes
kBootSignatureEQU 0xAA55; boot sector signature
kHFSPSignatureEQU 'H+'; HFS+ volume signature
kHFSPCaseSignatureEQU 'HX'; HFS+ volume case-sensitive signature
kFAT32BootCodeOffset EQU 0x5a; offset of boot code in FAT32 boot sector
kBoot1FAT32MagicEQU 'BO'; Magic string to detect our boot1f32 code
kGPTSignatureLowEQU 'EFI '; GUID Partition Table Header Signature
kGPTSignatureHighEQU 'PART'
kGUIDLastDwordOffsEQU 12; last 4 byte offset of a GUID
kPartCountEQU 4; number of paritions per table
kPartTypeHFSEQU 0xaf; HFS+ Filesystem type
kPartTypePMBREQU 0xee; On all GUID Partition Table disks a Protective MBR (PMBR)
; in LBA 0 (that is, the first block) precedes the
; GUID Partition Table Header to maintain compatibility
; with existing tools that do not understand GPT partition structures.
; The Protective MBR has the same format as a legacy MBR
; and contains one partition entry with an OSType set to 0xEE
; reserving the entire space used on the disk by the GPT partitions,
; including all headers.
kPartActive EQU 0x80; active flag enabled
kPartInactive EQU 0x00; active flag disabled
kHFSGUID EQU 0x48465300; first 4 bytes of Apple HFS Partition Type GUID.
kAppleGUIDEQU 0xACEC4365; last 4 bytes of Apple type GUIDs.
kEFISystemGUIDEQU 0x3BC93EC9; last 4 bytes of EFI System Partition Type GUID:
; C12A7328-F81F-11D2-BA4B-00A0C93EC93B
%ifdef FLOPPY
kDriveNumberEQU 0x00
%else
kDriveNumberEQU 0x80
%endif
;
; Format of fdisk partition entry.
;
; The symbol 'part_size' is automatically defined as an `EQU'
; giving the size of the structure.
;
struc part
.bootid resb 1 ; bootable or not
.head resb 1 ; starting head, sector, cylinder
.sect resb 1 ;
.cyl resb 1 ;
.type resb 1 ; partition type
.endhead resb 1 ; ending head, sector, cylinder
.endsect resb 1 ;
.endcyl resb 1 ;
.lba resd 1 ; starting lba
.sectors resd 1 ; size in sectors
endstruc
;
; Format of GPT Partition Table Header
;
strucgpth
.Signature resb8
.Revision resb4
.HeaderSizeresb4
.HeaderCRC32resb4
.Reservedresb4
.MyLBAresb8
.AlternateLBAresb8
.FirstUsableLBAresb8
.LastUsableLBAresb8
.DiskGUIDresb16
.PartitionEntryLBAresb8
.NumberOfPartitionEntriesresb4
.SizeOfPartitionEntryresb4
.PartitionEntryArrayCRC32resb4
endstruc
;
; Format of GUID Partition Entry Array
;
strucgpta
.PartitionTypeGUIDresb16
.UniquePartitionGUIDresb16
.StartingLBAresb8
.EndingLBAresb8
.Attributesresb8
.PartitionNameresb72
endstruc
;
; Macros.
;
%macro DebugCharMacro 1
mov al, %1
call print_char
%endmacro
%macro LogString 1
mov di, %1
call log_string
%endmacro
%if DEBUG
%define DebugChar(x) DebugCharMacro x
%else
%define DebugChar(x)
%endif
;--------------------------------------------------------------------------
; Start of text segment.
SEGMENT .text
ORG kBoot0RelocAddr
;--------------------------------------------------------------------------
; Boot code is loaded at 0:7C00h.
;
start:
;
; Set up the stack to grow down from kBoot0Segment:kBoot0Stack.
; Interrupts should be off while the stack is being manipulated.
;
cli ; interrupts off
xor ax, ax ; zero ax
mov ss, ax ; ss <- 0
mov sp, kBoot0Stack ; sp <- top of stack
sti ; reenable interrupts
mov es, ax ; es <- 0
mov ds, ax ; ds <- 0
;
; Relocate boot0 code.
;
mov si, kBoot0LoadAddr ; si <- source
mov di, kBoot0RelocAddr ; di <- destination
cld ; auto-increment SI and/or DI registers
mov cx, kSectorBytes/2 ; copy 256 words
repnz movsw ; repeat string move (word) operation
;
; Code relocated, jump to start_reloc in relocated location.
;
jmp kBoot0Segment:start_reloc
;--------------------------------------------------------------------------
; Start execution from the relocated location.
;
start_reloc:
DebugChar('>')
%if DEBUG
mov al, dl
call print_hex
%endif
;
; Since this code may not always reside in the MBR, always start by
; loading the MBR to kMBRBuffer and LBA1 to kGPTBuffer.
;
xor eax, eax
mov [my_lba], eax; store LBA sector 0 for read_lba function
mov al, 2; load two sectors: MBR and LBA1
mov bx, kMBRBuffer; MBR load address
call load
jc error; MBR load error
;
; Look for the booter partition in the MBR partition table,
; which is at offset kMBRPartTable.
;
mov si, kMBRPartTable; pointer to partition table
call find_boot; will not return on success
error:
LogString(boot_error_str)
hang:
hlt
jmp hang
;--------------------------------------------------------------------------
; Find the active (boot) partition and load the booter from the partition.
;
; Arguments:
; DL = drive number (0x80 + unit number)
; SI = pointer to fdisk partition table.
;
; Clobber list:
; EAX, BX, EBP
;
find_boot:
;
; Check for boot block signature 0xAA55 following the 4 partition
; entries.
;
cmp WORD [si + part_size * kPartCount], kBootSignature
jne .exit ; boot signature not found.
xor bx, bx; BL will be set to 1 later in case of
; Protective MBR has been found
inc bh; BH = 1. Giving a chance for a second pass
; to boot an inactive but boot1h aware HFS+ partition
; by scanning the MBR partition entries again.
.start_scan:
mov cx, kPartCount ; number of partition entries per table
.loop:
;
; First scan through the partition table looking for the active
; partition.
;
%if DEBUG
mov al, [si + part.type] ; print partition type
call print_hex
%endif
mov eax, [si + part.lba]; save starting LBA of current
mov [my_lba], eax; MBR partition entry for read_lba function
cmp BYTE [si + part.type], 0; unused partition?
je .continue ; skip to next entry
cmp BYTE [si + part.type], kPartTypePMBR; check for Protective MBR
jne .testPass
mov BYTE [si + part.bootid], kPartInactive; found Protective MBR
; clear active flag to make sure this protective
; partition won't be used as a bootable partition.
mov bl, 1; Assume we can deal with GPT but try to scan
; later if not found any other bootable partitions.
.testPass:
cmp bh, 1
jne .Pass2
.Pass1:
cmp BYTE [si + part.type], kPartTypeHFS; In pass 1 we're going to find a HFS+ partition
; equipped with boot1h in its boot record
; regardless if it's active or not.
jne .continue
movdh, 1 ; Argument for loadBootSector to check HFS+ partition signature.
jmp .tryToBoot
.Pass2:
cmp BYTE [si + part.bootid], kPartActive; In pass 2 we are walking on the standard path
; by trying to hop on the active partition.
jne .continue
xordh, dh ; Argument for loadBootSector to skip HFS+ partition
; signature check.
DebugChar('*')
;
; Found boot partition, read boot sector to memory.
;
.tryToBoot:
call loadBootSector
jne .continue
jmp SHORT initBootLoader
.continue:
add si, BYTE part_size ; advance SI to next partition entry
loop .loop ; loop through all partition entries
;
; Scanned all partitions but not found any with active flag enabled
; Anyway if we found a protective MBR before we still have a chance
; for a possible GPT Header at LBA 1
;
dec bl
jnz .switchPass2; didn't find Protective MBR before
call checkGPT
.switchPass2:
;
; Switching to Pass 2
; try to find a boot1h aware HFS+ MBR partition
;
dec bh
mov si, kMBRPartTable; set SI to first entry of MBR Partition table
jz .start_scan; scan again
.exit:
ret; Giving up.
;
; Jump to partition booter. The drive number is already in register DL.
; SI is pointing to the modified partition entry.
;
initBootLoader:
DebugChar('J')
%if VERBOSE
LogString(done_str)
%endif
jmp kBoot0LoadAddr
;
; Found Protective MBR Partition Type: 0xEE
; Check for 'EFI PART' string at the beginning
; of LBA1 for possible GPT Table Header
;
checkGPT:
push bx
mov di, kLBA1Buffer; address of GUID Partition Table Header
cmp DWORD [di], kGPTSignatureLow; looking for 'EFI '
jne .exit; not found. Giving up.
cmp DWORD [di + 4], kGPTSignatureHigh ; looking for 'PART'
jne .exit; not found. Giving up indeed.
mov si, di
;
; Loading GUID Partition Table Array
;
mov eax, [si + gpth.PartitionEntryLBA] ; starting LBA of GPT Array
mov [my_lba], eax; save starting LBA for read_lba function
mov cx, [si + gpth.NumberOfPartitionEntries]; number of GUID Partition Array entries
mov bx, [si + gpth.SizeOfPartitionEntry]; size of GUID Partition Array entry
push bx; push size of GUID Partition entry
;
; Calculating number of sectors we need to read for loading a GPT Array
;
; push dx; preserve DX (DL = BIOS drive unit number)
; mov ax, cx; AX * BX = number of entries * size of one entry
; mul bx; AX = total byte size of GPT Array
; pop dx; restore DX
; shr ax, 9; convert to sectors
;
; ... or:
; Current GPT Arrays uses 128 partition entries each 128 bytes long
; 128 entries * 128 bytes long GPT Array entries / 512 bytes per sector = 32 sectors
;
moval, 32; maximum sector size of GPT Array (hardcoded method)
mov bx, kGPTABuffer
push bx; push address of GPT Array
call load; read GPT Array
pop si; SI = address of GPT Array
pop bx; BX = size of GUID Partition Array entry
jc error
;
; Walk through GUID Partition Table Array
; and load boot record from first available HFS+ partition.
;
; If it has boot signature (0xAA55) then jump to it
; otherwise skip to next partition.
;
%if VERBOSE
LogString(gpt_str)
%endif
.gpt_loop:
mov eax, [si + gpta.PartitionTypeGUID + kGUIDLastDwordOffs]
cmpeax, kAppleGUID; check current GUID Partition for Apple's GUID type
je.gpt_ok
;
; Turbo - also try EFI System Partition
;
cmpeax, kEFISystemGUID; check current GUID Partition for EFI System Partition GUID type
jne.gpt_continue
.gpt_ok:
;
; Found HFS Partition
;
mov eax, [si + gpta.StartingLBA]; load boot sector from StartingLBA
mov [my_lba], eax
movdh, 1; Argument for loadBootSector to check HFS+ partition signature.
call loadBootSector
jne .gpt_continue; no boot loader signature
mov si, kMBRPartTable; fake the current GUID Partition
mov [si + part.lba], eax; as MBR style partition for boot1h
mov BYTE [si + part.type], kPartTypeHFS; with HFS+ filesystem type (0xAF)
jmp SHORT initBootLoader
.gpt_continue:
add si, bx; advance SI to next partition entry
loop .gpt_loop; loop through all partition entries
.exit:
pop bx
ret; no more GUID partitions. Giving up.
;--------------------------------------------------------------------------
; loadBootSector - Load boot sector
;
; Arguments:
; DL = drive number (0x80 + unit number)
; DH = 0 skip HFS+ partition signature checking
; 1 enable HFS+ partition signature checking
; [my_lba] = starting LBA.
;
; Returns:
; ZF = 0 if boot sector hasn't kBootSignature
; 1 if boot sector has kBootSignature
;
loadBootSector:
pusha
mov al, 3
mov bx, kBoot0LoadAddr
call load
jc error
ordh, dh
jz.checkBootSignature
.checkHFSSignature:
%if VERBOSE
LogString(test_str)
%endif
;
; Looking for HFSPlus ('H+') or HFSPlus case-sensitive ('HX') signature.
;
movax, [kBoot0LoadAddr + 2 * kSectorBytes]
cmp ax, kHFSPSignature; 'H+'
je.checkBootSignature
cmpax, kHFSPCaseSignature; 'HX'
je.checkBootSignature
;
; Looking for boot1f32 magic string.
;
movax, [kBoot0LoadAddr + kFAT32BootCodeOffset]
cmpax, kBoot1FAT32Magic
jne .exit
.checkBootSignature:
;
; Check for boot block signature 0xAA55
;
mov di, bx
cmp WORD [di + kSectorBytes - 2], kBootSignature
.exit:
popa
ret
;--------------------------------------------------------------------------
; load - Load one or more sectors from a partition.
;
; Arguments:
; AL = number of 512-byte sectors to read.
; ES:BX = pointer to where the sectors should be stored.
; DL = drive number (0x80 + unit number)
; [my_lba] = starting LBA.
;
; Returns:
; CF = 0 success
; 1 error
;
load:
push cx
.ebios:
mov cx, 5 ; load retry count
.ebios_loop:
call read_lba ; use INT13/F42
jnc .exit
loop .ebios_loop
.exit:
pop cx
ret
;--------------------------------------------------------------------------
; read_lba - Read sectors from a partition using LBA addressing.
;
; Arguments:
; AL = number of 512-byte sectors to read (valid from 1-127).
; ES:BX = pointer to where the sectors should be stored.
; DL = drive number (0x80 + unit number)
; [my_lba] = starting LBA.
;
; Returns:
; CF = 0 success
; 1 error
;
read_lba:
pushad ; save all registers
mov bp, sp ; save current SP
;
; Create the Disk Address Packet structure for the
; INT13/F42 (Extended Read Sectors) on the stack.
;
; push DWORD 0 ; offset 12, upper 32-bit LBA
push ds ; For sake of saving memory,
push ds ; push DS register, which is 0.
mov ecx, [my_lba] ; offset 8, lower 32-bit LBA
push ecx
push es ; offset 6, memory segment
push bx ; offset 4, memory offset
xor ah, ah ; offset 3, must be 0
push ax ; offset 2, number of sectors
; It pushes 2 bytes with a smaller opcode than if WORD was used
push BYTE 16 ; offset 0-1, packet size
DebugChar('<')
%if DEBUG
mov eax, ecx
call print_hex
%endif
;
; INT13 Func 42 - Extended Read Sectors
;
; Arguments:
; AH = 0x42
; DL = drive number (80h + drive unit)
; DS:SI = pointer to Disk Address Packet
;
; Returns:
; AH = return status (sucess is 0)
; carry = 0 success
; 1 error
;
; Packet offset 2 indicates the number of sectors read
; successfully.
;
mov si, sp
mov ah, 0x42
int 0x13
jnc .exit
DebugChar('R') ; indicate INT13/F42 error
;
; Issue a disk reset on error.
; Should this be changed to Func 0xD to skip the diskette controller
; reset?
;
xor ax, ax ; Func 0
int 0x13 ; INT 13
stc ; set carry to indicate error
.exit:
mov sp, bp ; restore SP
popad
ret
;--------------------------------------------------------------------------
; Write a string with 'boot0: ' prefix to the console.
;
; Arguments:
; ES:DI pointer to a NULL terminated string.
;
; Clobber list:
; DI
;
log_string:
pusha
pushdi
movsi, log_title_str
callprint_string
popsi
callprint_string
popa
ret
;--------------------------------------------------------------------------
; Write a string to the console.
;
; Arguments:
; DS:SI pointer to a NULL terminated string.
;
; Clobber list:
; AX, BX, SI
;
print_string:
mov bx, 1 ; BH=0, BL=1 (blue)
cld ; increment SI after each lodsb call
.loop:
lodsb ; load a byte from DS:SI into AL
cmp al, 0 ; Is it a NULL?
je .exit ; yes, all done
mov ah, 0xE ; INT10 Func 0xE
int 0x10 ; display byte in tty mode
jmp short .loop
.exit:
ret
%if DEBUG
;--------------------------------------------------------------------------
; Write a ASCII character to the console.
;
; Arguments:
; AL = ASCII character.
;
print_char:
pusha
mov bx, 1 ; BH=0, BL=1 (blue)
mov ah, 0x0e ; bios INT 10, Function 0xE
int 0x10 ; display byte in tty mode
popa
ret
;--------------------------------------------------------------------------
; Write the 4-byte value to the console in hex.
;
; Arguments:
; EAX = Value to be displayed in hex.
;
print_hex:
pushad
mov cx, WORD 4
bswap eax
.loop:
push ax
ror al, 4
call print_nibble ; display upper nibble
pop ax
call print_nibble ; display lower nibble
ror eax, 8
loop .loop
mov al, 10 ; carriage return
call print_char
mov al, 13
call print_char
popad
ret
print_nibble:
and al, 0x0f
add al, '0'
cmp al, '9'
jna .print_ascii
add al, 'A' - '9' - 1
.print_ascii:
call print_char
ret
getc:
pusha
mov ah, 0
int 0x16
popa
ret
%endif ;DEBUG
;--------------------------------------------------------------------------
; NULL terminated strings.
;
log_title_strdb 10, 13, 'boot0: ', 0
boot_error_str db 'error', 0
%if VERBOSE
gpt_strdb 'GPT', 0
test_strdb 'test', 0
done_strdb 'done', 0
%endif
;--------------------------------------------------------------------------
; Pad the rest of the 512 byte sized booter with zeroes. The last
; two bytes is the mandatory boot sector signature.
;
; If the booter code becomes too large, then nasm will complain
; that the 'times' argument is negative.
;
; According to EFI specification, maximum boot code size is 440 bytes
;
;
; XXX - compilation errors with debug enabled (see comment above about nasm)
; Azi: boot0.s:808: error: TIMES value -111 is negative
; boot0.s:811: error: TIMES value -41 is negative
;
pad_boot:
times 440-($-$$) db 0
pad_table_and_sig:
times 510-($-$$) db 0
dw kBootSignature
ABSOLUTE 0xE400
;
; In memory variables.
;
my_lbaresd1; Starting LBA for read_lba function
; END
branches/azimutz/trunkAutoResolution/i386/boot0/boot0md.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
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
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
; Copyright (c) 1999-2003 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@
;
; Boot Loader: boot0
;
; A small boot sector program written in x86 assembly whose only
; responsibility is to locate the active partition, load the
; partition booter into memory, and jump to the booter's entry point.
; It leaves the boot drive in DL and a pointer to the partition entry in SI.
;
; This boot loader must be placed in the Master Boot Record.
;
; In order to coexist with a fdisk partition table (64 bytes), and
; leave room for a two byte signature (0xAA55) in the end, boot0 is
; restricted to 446 bytes (512 - 64 - 2). If boot0 did not have to
; live in the MBR, then we would have 510 bytes to work with.
;
; boot0 is always loaded by the BIOS or another booter to 0:7C00h.
;
; This code is written for the NASM assembler.
; nasm boot0.s -o boot0
;
; This version of boot0 implements hybrid GUID/MBR partition scheme support
;
;
; Turbo added EFI System Partition boot support
;
; Added KillerJK's switchPass2 modifications
;
; dmazar: 10/7/2011 added scanning of all BIOS accessible drives:
; - iterates over all drives and searches for HSF bootable partition (with boot1h)
; and loads from it
; - if not found, itarates over drives again and searches for active partition and
; loads from it
;
;
; Set to 1 to enable obscure debug messages.
;
DEBUGEQU CONFIG_BOOT0_DEBUG
;
; Set to 1 to enable verbose mode
;
VERBOSEEQU CONFIG_BOOT0_VERBOSE
;
; Various constants.
;
kBoot0SegmentEQU 0x0000
kBoot0StackEQU 0xFFF0; boot0 stack pointer
kBoot0LoadAddrEQU 0x7C00; boot0 load address
kBoot0RelocAddrEQU 0xE000; boot0 relocated address
kMBRBufferEQU 0x1000; MBR buffer address
kLBA1BufferEQU 0x1200; LBA1 - GPT Partition Table Header buffer address
kGPTABufferEQU 0x1400; GUID Partition Entry Array buffer address
kPartTableOffsetEQU 0x1be
kMBRPartTableEQU kMBRBuffer + kPartTableOffset
kSectorBytesEQU 512; sector size in bytes
kBootSignatureEQU 0xAA55; boot sector signature
kHFSPSignatureEQU 'H+'; HFS+ volume signature
kHFSPCaseSignatureEQU 'HX'; HFS+ volume case-sensitive signature
kFAT32BootCodeOffset EQU 0x5a; offset of boot code in FAT32 boot sector
kBoot1FAT32MagicEQU 'BO'; Magic string to detect our boot1f32 code
kGPTSignatureLowEQU 'EFI '; GUID Partition Table Header Signature
kGPTSignatureHighEQU 'PART'
kGUIDLastDwordOffsEQU 12; last 4 byte offset of a GUID
kPartCountEQU 4; number of paritions per table
kPartTypeHFSEQU 0xaf; HFS+ Filesystem type
kPartTypePMBREQU 0xee; On all GUID Partition Table disks a Protective MBR (PMBR)
; in LBA 0 (that is, the first block) precedes the
; GUID Partition Table Header to maintain compatibility
; with existing tools that do not understand GPT partition structures.
; The Protective MBR has the same format as a legacy MBR
; and contains one partition entry with an OSType set to 0xEE
; reserving the entire space used on the disk by the GPT partitions,
; including all headers.
kPartActive EQU 0x80; active flag enabled
kPartInactive EQU 0x00; active flag disabled
kHFSGUID EQU 0x48465300; first 4 bytes of Apple HFS Partition Type GUID.
kAppleGUIDEQU 0xACEC4365; last 4 bytes of Apple type GUIDs.
kEFISystemGUIDEQU 0x3BC93EC9; last 4 bytes of EFI System Partition Type GUID:
; C12A7328-F81F-11D2-BA4B-00A0C93EC93B
%ifdef FLOPPY
kDriveNumberEQU 0x00
%else
kDriveNumberEQU 0x80
%endif
;
; Format of fdisk partition entry.
;
; The symbol 'part_size' is automatically defined as an `EQU'
; giving the size of the structure.
;
struc part
.bootid resb 1 ; bootable or not
.head resb 1 ; starting head, sector, cylinder
.sect resb 1 ;
.cyl resb 1 ;
.type resb 1 ; partition type
.endhead resb 1 ; ending head, sector, cylinder
.endsect resb 1 ;
.endcyl resb 1 ;
.lba resd 1 ; starting lba
.sectors resd 1 ; size in sectors
endstruc
;
; Format of GPT Partition Table Header
;
strucgpth
.Signature resb8
.Revision resb4
.HeaderSizeresb4
.HeaderCRC32resb4
.Reservedresb4
.MyLBAresb8
.AlternateLBAresb8
.FirstUsableLBAresb8
.LastUsableLBAresb8
.DiskGUIDresb16
.PartitionEntryLBAresb8
.NumberOfPartitionEntriesresb4
.SizeOfPartitionEntryresb4
.PartitionEntryArrayCRC32resb4
endstruc
;
; Format of GUID Partition Entry Array
;
strucgpta
.PartitionTypeGUIDresb16
.UniquePartitionGUIDresb16
.StartingLBAresb8
.EndingLBAresb8
.Attributesresb8
.PartitionNameresb72
endstruc
;
; Macros.
;
%macro DebugCharMacro 1
mov al, %1
call print_char
%endmacro
%macro LogString 1
mov di, %1
call log_string
%endmacro
%if DEBUG
%define DebugChar(x) DebugCharMacro x
%else
%define DebugChar(x)
%endif
;--------------------------------------------------------------------------
; Start of text segment.
SEGMENT .text
ORG kBoot0RelocAddr
;--------------------------------------------------------------------------
; Boot code is loaded at 0:7C00h.
;
start:
;
; Set up the stack to grow down from kBoot0Segment:kBoot0Stack.
; Interrupts should be off while the stack is being manipulated.
;
cli ; interrupts off
xor ax, ax ; zero ax
mov ss, ax ; ss <- 0
mov sp, kBoot0Stack ; sp <- top of stack
sti ; reenable interrupts
mov es, ax ; es <- 0
mov ds, ax ; ds <- 0
;
; Relocate boot0 code.
;
mov si, kBoot0LoadAddr ; si <- source
mov di, kBoot0RelocAddr ; di <- destination
cld ; auto-increment SI and/or DI registers
mov cx, kSectorBytes/2 ; copy 256 words
repnz movsw ; repeat string move (word) operation
;
; Code relocated, jump to start_reloc in relocated location.
;
jmp kBoot0Segment:start_reloc
;--------------------------------------------------------------------------
; Start execution from the relocated location.
;
start_reloc:
pushdx; save dl (boot drive) for second pass.
; will stay on stack if booter loaded in first pass.
; this should not be a problem
movbh, 1; BH = 1. two pass scanning (active or hfs partition).
; actuall use of it (scanning) is in find_boot
scan_drives:
DebugChar('>')
%if DEBUG
mov al, dl
call print_hex
%endif
;
; Since this code may not always reside in the MBR, always start by
; loading the MBR to kMBRBuffer and LBA1 to kGPTBuffer.
;
pushbx; save BH (scan pass counter)
xor eax, eax
mov [my_lba], eax; store LBA sector 0 for read_lba function
mov al, 2; load two sectors: MBR and LBA1
mov bx, kMBRBuffer; MBR load address
call load
popbx; restore BH
jc .mbr_load_error; MBR load error - normally because we scanned all drives
;
; Look for the booter partition in the MBR partition table,
; which is at offset kMBRPartTable.
;
mov si, kMBRPartTable; pointer to partition table
call find_boot; will not return on success
; if returns - booter partition not found
; try next drive
; if next drive does not exists - will break on above MBR load error
incdl
jmpscan_drives
.mbr_load_error:
; all drives scanned - see if we need to run second pass
popdx; restore orig boot drive
decbh; decrement scan pass counter
jzscan_drives; if zero - run seccond pass
; we ran two passes - nothing found - error
error:
LogString(boot_error_str)
hang:
hlt
jmp hang
;--------------------------------------------------------------------------
; Find the active (boot) partition and load the booter from the partition.
;
; Arguments:
; DL = drive number (0x80 + unit number)
; SI = pointer to fdisk partition table.
; BH = pass counter (1=first pass, 0=second pass)
;
; Clobber list:
; EAX, BX, EBP
;
find_boot:
;
; Check for boot block signature 0xAA55 following the 4 partition
; entries.
;
cmp WORD [si + part_size * kPartCount], kBootSignature
jne .exit ; boot signature not found.
xor bl, bl; BL will be set to 1 later in case of
; Protective MBR has been found
.start_scan:
mov cx, kPartCount ; number of partition entries per table
.loop:
;
; First scan through the partition table looking for the active
; partition.
;
%if DEBUG
mov al, [si + part.type] ; print partition type
call print_hex
%endif
mov eax, [si + part.lba]; save starting LBA of current
mov [my_lba], eax; MBR partition entry for read_lba function
cmp BYTE [si + part.type], 0; unused partition?
je .continue ; skip to next entry
cmp BYTE [si + part.type], kPartTypePMBR; check for Protective MBR
jne .testPass
mov BYTE [si + part.bootid], kPartInactive; found Protective MBR
; clear active flag to make sure this protective
; partition won't be used as a bootable partition.
mov bl, 1; Assume we can deal with GPT but try to scan
; later if not found any other bootable partitions.
.testPass:
cmp bh, 1
jne .Pass2
.Pass1:
cmp BYTE [si + part.type], kPartTypeHFS; In pass 1 we're going to find a HFS+ partition
; equipped with boot1h in its boot record
; regardless if it's active or not.
jne .continue
movdh, 1 ; Argument for loadBootSector to check HFS+ partition signature.
jmp .tryToBoot
.Pass2:
cmp BYTE [si + part.bootid], kPartActive; In pass 2 we are walking on the standard path
; by trying to hop on the active partition.
jne .continue
xordh, dh ; Argument for loadBootSector to skip HFS+ partition
; signature check.
DebugChar('*')
;
; Found boot partition, read boot sector to memory.
;
.tryToBoot:
call loadBootSector
jne .continue
jmp SHORT initBootLoader
.continue:
add si, BYTE part_size ; advance SI to next partition entry
loop .loop ; loop through all partition entries
;
; Scanned all partitions but not found any with active flag enabled
; Anyway if we found a protective MBR before we still have a chance
; for a possible GPT Header at LBA 1
;
dec bl
jnz .exit; didn't find Protective MBR before
call checkGPT
.exit:
ret; Giving up.
;
; Jump to partition booter. The drive number is already in register DL.
; SI is pointing to the modified partition entry.
;
initBootLoader:
DebugChar('J')
%if VERBOSE
LogString(done_str)
%endif
jmp kBoot0LoadAddr
;
; Found Protective MBR Partition Type: 0xEE
; Check for 'EFI PART' string at the beginning
; of LBA1 for possible GPT Table Header
;
checkGPT:
push bx
mov di, kLBA1Buffer; address of GUID Partition Table Header
cmp DWORD [di], kGPTSignatureLow; looking for 'EFI '
jne .exit; not found. Giving up.
cmp DWORD [di + 4], kGPTSignatureHigh ; looking for 'PART'
jne .exit; not found. Giving up indeed.
mov si, di
;
; Loading GUID Partition Table Array
;
mov eax, [si + gpth.PartitionEntryLBA] ; starting LBA of GPT Array
mov [my_lba], eax; save starting LBA for read_lba function
mov cx, [si + gpth.NumberOfPartitionEntries]; number of GUID Partition Array entries
mov bx, [si + gpth.SizeOfPartitionEntry]; size of GUID Partition Array entry
push bx; push size of GUID Partition entry
;
; Calculating number of sectors we need to read for loading a GPT Array
;
; push dx; preserve DX (DL = BIOS drive unit number)
; mov ax, cx; AX * BX = number of entries * size of one entry
; mul bx; AX = total byte size of GPT Array
; pop dx; restore DX
; shr ax, 9; convert to sectors
;
; ... or:
; Current GPT Arrays uses 128 partition entries each 128 bytes long
; 128 entries * 128 bytes long GPT Array entries / 512 bytes per sector = 32 sectors
;
moval, 32; maximum sector size of GPT Array (hardcoded method)
mov bx, kGPTABuffer
push bx; push address of GPT Array
call load; read GPT Array
pop si; SI = address of GPT Array
pop bx; BX = size of GUID Partition Array entry
jc error
;
; Walk through GUID Partition Table Array
; and load boot record from first available HFS+ partition.
;
; If it has boot signature (0xAA55) then jump to it
; otherwise skip to next partition.
;
%if VERBOSE
LogString(gpt_str)
%endif
.gpt_loop:
mov eax, [si + gpta.PartitionTypeGUID + kGUIDLastDwordOffs]
cmpeax, kAppleGUID; check current GUID Partition for Apple's GUID type
je.gpt_ok
;
; Turbo - also try EFI System Partition
;
cmpeax, kEFISystemGUID; check current GUID Partition for EFI System Partition GUID type
jne.gpt_continue
.gpt_ok:
;
; Found HFS Partition
;
mov eax, [si + gpta.StartingLBA]; load boot sector from StartingLBA
mov [my_lba], eax
movdh, 1; Argument for loadBootSector to check HFS+ partition signature.
call loadBootSector
jne .gpt_continue; no boot loader signature
mov si, kMBRPartTable; fake the current GUID Partition
mov [si + part.lba], eax; as MBR style partition for boot1h
mov BYTE [si + part.type], kPartTypeHFS; with HFS+ filesystem type (0xAF)
jmp SHORT initBootLoader
.gpt_continue:
add si, bx; advance SI to next partition entry
loop .gpt_loop; loop through all partition entries
.exit:
pop bx
ret; no more GUID partitions. Giving up.
;--------------------------------------------------------------------------
; loadBootSector - Load boot sector
;
; Arguments:
; DL = drive number (0x80 + unit number)
; DH = 0 skip HFS+ partition signature checking
; 1 enable HFS+ partition signature checking
; [my_lba] = starting LBA.
;
; Returns:
; ZF = 0 if boot sector hasn't kBootSignature
; 1 if boot sector has kBootSignature
;
loadBootSector:
pusha
mov al, 3
mov bx, kBoot0LoadAddr
call load
jc error
ordh, dh
jz.checkBootSignature
.checkHFSSignature:
%if VERBOSE
;LogString(test_str); dmazar: removed to get space
%endif
;
; Looking for HFSPlus ('H+') or HFSPlus case-sensitive ('HX') signature.
;
movax, [kBoot0LoadAddr + 2 * kSectorBytes]
cmp ax, kHFSPSignature; 'H+'
je.checkBootSignature
cmpax, kHFSPCaseSignature; 'HX'
je.checkBootSignature
;
; Looking for boot1f32 magic string.
;
movax, [kBoot0LoadAddr + kFAT32BootCodeOffset]
cmpax, kBoot1FAT32Magic
jne .exit
.checkBootSignature:
;
; Check for boot block signature 0xAA55
;
mov di, bx
cmp WORD [di + kSectorBytes - 2], kBootSignature
.exit:
popa
ret
;--------------------------------------------------------------------------
; load - Load one or more sectors from a partition.
;
; Arguments:
; AL = number of 512-byte sectors to read.
; ES:BX = pointer to where the sectors should be stored.
; DL = drive number (0x80 + unit number)
; [my_lba] = starting LBA.
;
; Returns:
; CF = 0 success
; 1 error
;
load:
push cx
.ebios:
mov cx, 5 ; load retry count
.ebios_loop:
call read_lba ; use INT13/F42
jnc .exit
loop .ebios_loop
.exit:
pop cx
ret
;--------------------------------------------------------------------------
; read_lba - Read sectors from a partition using LBA addressing.
;
; Arguments:
; AL = number of 512-byte sectors to read (valid from 1-127).
; ES:BX = pointer to where the sectors should be stored.
; DL = drive number (0x80 + unit number)
; [my_lba] = starting LBA.
;
; Returns:
; CF = 0 success
; 1 error
;
read_lba:
pushad ; save all registers
mov bp, sp ; save current SP
;
; Create the Disk Address Packet structure for the
; INT13/F42 (Extended Read Sectors) on the stack.
;
; push DWORD 0 ; offset 12, upper 32-bit LBA
push ds ; For sake of saving memory,
push ds ; push DS register, which is 0.
mov ecx, [my_lba] ; offset 8, lower 32-bit LBA
push ecx
push es ; offset 6, memory segment
push bx ; offset 4, memory offset
xor ah, ah ; offset 3, must be 0
push ax ; offset 2, number of sectors
; It pushes 2 bytes with a smaller opcode than if WORD was used
push BYTE 16 ; offset 0-1, packet size
DebugChar('<')
%if DEBUG
mov eax, ecx
call print_hex
%endif
;
; INT13 Func 42 - Extended Read Sectors
;
; Arguments:
; AH = 0x42
; DL = drive number (80h + drive unit)
; DS:SI = pointer to Disk Address Packet
;
; Returns:
; AH = return status (sucess is 0)
; carry = 0 success
; 1 error
;
; Packet offset 2 indicates the number of sectors read
; successfully.
;
mov si, sp
mov ah, 0x42
int 0x13
jnc .exit
DebugChar('R') ; indicate INT13/F42 error
;
; Issue a disk reset on error.
; Should this be changed to Func 0xD to skip the diskette controller
; reset?
;
xor ax, ax ; Func 0
int 0x13 ; INT 13
stc ; set carry to indicate error
.exit:
mov sp, bp ; restore SP
popad
ret
;--------------------------------------------------------------------------
; Write a string with 'boot0: ' prefix to the console.
;
; Arguments:
; ES:DI pointer to a NULL terminated string.
;
; Clobber list:
; DI
;
log_string:
pusha
pushdi
movsi, log_title_str
callprint_string
popsi
callprint_string
popa
ret
;--------------------------------------------------------------------------
; Write a string to the console.
;
; Arguments:
; DS:SI pointer to a NULL terminated string.
;
; Clobber list:
; AX, BX, SI
;
print_string:
mov bx, 1 ; BH=0, BL=1 (blue)
cld ; increment SI after each lodsb call
.loop:
lodsb ; load a byte from DS:SI into AL
cmp al, 0 ; Is it a NULL?
je .exit ; yes, all done
mov ah, 0xE ; INT10 Func 0xE
int 0x10 ; display byte in tty mode
jmp short .loop
.exit:
ret
%if DEBUG
;--------------------------------------------------------------------------
; Write a ASCII character to the console.
;
; Arguments:
; AL = ASCII character.
;
print_char:
pusha
mov bx, 1 ; BH=0, BL=1 (blue)
mov ah, 0x0e ; bios INT 10, Function 0xE
int 0x10 ; display byte in tty mode
popa
ret
;--------------------------------------------------------------------------
; Write the 4-byte value to the console in hex.
;
; Arguments:
; EAX = Value to be displayed in hex.
;
print_hex:
pushad
mov cx, WORD 4
bswap eax
.loop:
push ax
ror al, 4
call print_nibble ; display upper nibble
pop ax
call print_nibble ; display lower nibble
ror eax, 8
loop .loop
mov al, 10 ; carriage return
call print_char
mov al, 13
call print_char
popad
ret
print_nibble:
and al, 0x0f
add al, '0'
cmp al, '9'
jna .print_ascii
add al, 'A' - '9' - 1
.print_ascii:
call print_char
ret
getc:
pusha
mov ah, 0
int 0x16
popa
ret
%endif ;DEBUG
;--------------------------------------------------------------------------
; NULL terminated strings.
;
log_title_strdb 10, 13, 'boot0: ', 0
boot_error_str db 'error', 0
%if VERBOSE
gpt_strdb 'GPT', 0
;test_strdb 'test', 0
done_strdb 'done', 0
%endif
;--------------------------------------------------------------------------
; Pad the rest of the 512 byte sized booter with zeroes. The last
; two bytes is the mandatory boot sector signature.
;
; If the booter code becomes too large, then nasm will complain
; that the 'times' argument is negative.
;
; According to EFI specification, maximum boot code size is 440 bytes
;
pad_boot:
times 440-($-$$) db 0
pad_table_and_sig:
times 510-($-$$) db 0
dw kBootSignature
ABSOLUTE 0xE400
;
; In memory variables.
;
my_lbaresd1; Starting LBA for read_lba function
; END
branches/azimutz/trunkAutoResolution/i386/boot0/Cconfig
1
2
3
4
5
6
7
81
92
103
config BOOT0_HFSFIRST
bool "boot0 HFS prefered"
default y
help
Say Y here if you want boot0 to attempt to boot the first
hfs partition found, instead of the active partition.
config BOOT0_DEBUG
bool "boot0 debug support"
default n
branches/azimutz/trunkAutoResolution/i386/boot0/Makefile
1313
1414
1515
16
16
1717
1818
1919
DIRS_NEEDED = $(SYMROOT)
OBJECTS = boot0 chain0
OBJECTS = boot0 boot0hfs boot0md chain0
OBJECTS := $(addprefix $(SYMROOT)/, $(OBJECTS))
all: $(DIRS_NEEDED) $(OBJECTS)
branches/azimutz/trunkAutoResolution/i386/boot2/drivers.c
746746
747747
748748
749
750
749
750
751
752
751753
752
754
753755
754756
755757
756
757758
758759
759760
if (length == -1) return -1;
#if 0 /** remove this check. **/
if (strcmp(XMLCastString(XMLGetProperty(moduleDict, kPropOSBundleRequired)), "Safe Boot") == 0)
if (!(gBootMode & kBootModeSafe) &&
XMLGetProperty(moduleDict, kPropOSBundleRequired) &&
strcmp(XMLCastString(XMLGetProperty(moduleDict, kPropOSBundleRequired)), "Safe Boot") == 0)
{
// Don't load Safe Boot kexts. NOTE: -x should be check too.
// Don't load Safe Boot kexts if -x not specified.
XMLFreeTag(moduleDict);
return -2;
}
#endif
tmpModule = malloc(sizeof(Module));
if (tmpModule == 0)
branches/azimutz/trunkAutoResolution/i386/boot2/boot.c
520520
521521
522522
523
523524
524525
525526
526527
527528
528529
529
530
530531
531532
532533
533534
534535
535
536
537
536
538537
539538
540539
......
573572
574573
575574
575
576576
577
577578
578579
579580
......
695696
696697
697698
698
699
699700
700
701
701702
702
703
703704
704
705
706
707
708
709
710
705
706
707
711708
712709
713710
714
715
711
712
713
714
715
716
717
716718
717
718719
719
720
720721
721722
722723
723
724
725
724726
725727
726
728
729
727730
728731
729732
730733
731734
732735
733
736
737
734738
735739
736740
737
741
742
738743
739744
740745
} else {
archCpuType = CPU_TYPE_I386;
}
if (getValueForKey(karch, &val, &len, &bootInfo->chameleonConfig)) {
if (strncmp(val, "i386", 4) == 0) {
archCpuType = CPU_TYPE_I386;
}
}
if (getValueForKey(kKernelArchKey, &val, &len, &bootInfo->chameleonConfig)) {
if (getValueForKey(kKernelArchKey, &val, &len, &bootInfo->chameleonConfig)) {
if (strncmp(val, "i386", 4) == 0) {
archCpuType = CPU_TYPE_I386;
}
}
//archCpuType = CPU_TYPE_I386;
// Notify moduals that we are attempting to boot
// Notify modules that we are attempting to boot
execute_hook("PreBoot", NULL, NULL, NULL, NULL);
if (!getBoolForKey (kWake, &tryresume, &bootInfo->chameleonConfig)) {
break;
if (!forceresume && ((sleeptime+3)<bvr->modTime)) {
#if DEBUG
printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n",bvr->modTime-sleeptime);
#endif
break;
}
verbose("Kernel cache did not load %s\n ", bootFile);
}
bootFile = bootInfo->bootFile;
// Try to load kernel image from alternate locations on boot helper partitions.
sprintf(bootFileSpec, "com.apple.boot.P/%s", bootFile);
sprintf(bootFileSpec, "com.apple.boot.P%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
sprintf(bootFileSpec, "com.apple.boot.R/%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
sprintf(bootFileSpec, "com.apple.boot.S/%s", bootFile);
if (ret == -1)
{
sprintf(bootFileSpec, "com.apple.boot.R%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
// No alternate location found, using the original kernel image path.
strcpy(bootFileSpec, bootFile);
sprintf(bootFileSpec, "com.apple.boot.S%s", bootFile);
ret = GetFileInfo(NULL, bootFileSpec, &flags, &time);
if (ret == -1)
{
// No alternate location found, using the original kernel image path.
strcpy(bootFileSpec, bootFile);
}
}
}
}
if (checkOSVersion("10.7"))
{
//Lion, dont load kernel if haz cache
if (!trycache) {
if (!trycache)
{
verbose("Loading kernel %s\n", bootFileSpec);
ret = LoadThinFatFile(bootFileSpec, &binary);
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64) {
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
{
archCpuType = CPU_TYPE_I386;
ret = LoadThinFatFile(bootFileSpec, &binary);
}
}
else ret = 1;
}
else {
else
{
//Snow Leopard or older
verbose("Loading kernel %s\n", bootFileSpec);
ret = LoadThinFatFile(bootFileSpec, &binary);
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64) {
if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
{
archCpuType = CPU_TYPE_I386;
ret = LoadThinFatFile(bootFileSpec, &binary);
}
branches/azimutz/trunkAutoResolution/i386/boot2/boot.h
8080
8181
8282
83
84
85
83
84
85
86
8687
8788
8889
......
107108
108109
109110
111
110112
111113
112114
#define kRestartFix"RestartFix"/* acpi_patcher.c */
#define kGeneratePStates"GeneratePStates"/* acpi_patcher.c */
#define kGenerateCStates"GenerateCStates"/* acpi_patcher.c */
#define kEnableC2States"EnableC2State"/* acpi_patcher.c */
#define kEnableC3States"EnableC3State"/* acpi_patcher.c */
#define kEnableC4States"EnableC4State"/* acpi_patcher.c */
#define kCSTUsingSystemIO"CSTUsingSystemIO"/* acpi_patcher.c */
#define kEnableC2State"EnableC2State"/* acpi_patcher.c */
#define kEnableC3State"EnableC3State"/* acpi_patcher.c */
#define kEnableC4State"EnableC4State"/* acpi_patcher.c */
#define kWake"Wake"/* boot.c */
#define kForceWake"ForceWake"/* boot.c */
#define kUseAtiROM"UseAtiROM"/* ati.c */
#define kAtiConfig"AtiConfig"/* ati.c */
#define kAtiPorts"AtiPorts"/* ati.c */
#define kATYbinimage"ATYbinimage"/* ati.c */
#define kUseNvidiaROM"UseNvidiaROM"/* nvidia.c */
branches/azimutz/trunkAutoResolution/package/Resources/Russian.lproj/Description.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Lucida Grande;}
</style>
</head>
<body>
<p class="p1">Chameleon квинтэссенцией технологий развитых для загрузки OSX,
<br />Он основан на проекте Apple's boot-132 <br /> и дополнен следующими функциями:</p>
<br />
<p class="p1">Новые возможности Chameleon 2.0</p>
<br>
<p class="p1"> - Эмуляция EFI.</p>
<p class="p1"> - Замена таблиц ACPI на более подходящие.</p>
<p class="p1"> - Исправления таблиц DMI на нужные.</p>
<p class="p1"> - Присвоение свойств встроенным устройствам, необходимых для запуска.</p>
<p class="p1"> - Запуск технологии энергосбережения.</p>
<br>
<p class="p1"> - Настраиваемый внешний вид.</p>
<p class="p1"> - Распознавание разных схем разделов диска.</p>
<p class="p1"> - Возможность установки на HDD, DVD и на USB.</p>
<p class="p1"> - другие технологии Apple.</p>
<br />
<p class="p1">Для детальной информации смотрите на сайте : <a href="http://www.applelife.ru">http://www.applelife.ru</a></p>
</body>
</html>
branches/azimutz/trunkAutoResolution/package/Resources/Russian.lproj/Localizable.strings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"Chameleon_title" = "Chameleon";
"Standard_title" = "Chameleon Standard";
"Standard_description" = "#AB0=>28BL Chameleon";
"EnhancedFAT_title" = "Chameleon EFI FAT";
"EnhancedFAT_description" = "#AB0=>28BL Chameleon =0 EFI System partition FAT32 (@838=0;L=CN)";
"EnhancedHFS_title" = "Chameleon EFI HFS";
"EnhancedHFS_description" = "#AB0=>28BL Chameleon =0 EFI System partition HFS (5@5D>@<0B8@>2BL 2 HFS)";
// Options
"Options_title" = "?F88";
"Options_description" = "K1>@ >?F89";
"GUI_title" = "@0D8G5A:0O 1>;>G:0 (@1=GUI)";
"GUI_description" = "0?@5B8BL @1, 2AB028BL GUI=n to org.chameleon.Boot.plist";
"EthernetBuiltIn_title" = "AB@>5==0O A5B520O";
"EthernetBuiltIn_description" = ">1028BL EthernetBuiltIn=y 2 .Boot.plist, -B0 >?F8O 4>102;O5B A2>9AB2> 'built-in' 4;O 2AB@>5==>9 A5B52>9.";
"ForceHPET_title" = ">4=OBL HPET";
"ForceHPET_description" = ">102;O5B ForceHPET=y 2.Boot.plist, -B0 >?F8O 70?CA:05B HPET =0 intel chipsets, 4065 5A;8 2 !5 MB> =5 A45;0=>.";
"EHCIacquire_title" = "EHCIacquire";
"EHCIacquire_description" = "Add EHCIacquire=y to com.apple.Boot.plist, This option fixes any EHCI ownership issues due to bad bioses.";
"UHCIreset_title" = "UHCIreset";
"UHCIreset_description" = "Add UHCIreset=y to com.apple.Boot.plist, This option will reset UHCI controllers before starting OS X.";
"GraphicsEnabler_title" = ":;NG8BL 3@0D8:C";
"GraphicsEnabler_description" = ">102;O5B GraphicsEnabler=YES 2 .Boot.plist, MB0 >?F8O 70?CA:05B <=>385 2845>:0@BK nVidia, ATI, Intel.";
// Themes
"Themes_title" = ""5<K 2=5H=53> 2840";
"Themes_description" = ">;;5:F8O C:@0H5=89";
"Default_title" = "Standard";
"Default_description" = "The theme thats embedded inside the booter, included here for you to customise.";
"Big_title" = "Big";
"Big_description" = "A theme with a large layout for you lucky people with big monitors";
"Twilight_title" = "Twilight";
"Twilight_description" = "A simple theme for the Twilight fans out there";
"Pinktink_title" = "PinkTink";
"Pinktink_description" = "A simple theme with a pink background and Tinkerbell";
"Msi_netbook_title" = "MSi Netbook";
"Msi_netbook_description" = "A simple MSi boot logo for your MSi netbook =)";
"Bullet_title" = "Bullet";
"Bullet_description" = "The Bullet theme by NoSmokingBandit";
// Extras
"Extras_title" = "Extras";
"Extras_description" = "A collection of useful addons";
"SMBios_title" = "SMBIOS Override";
"SMBios_description" = "Install default SMBIOS overrides smbios.plist into Extra";
// Kexts
"Kexts_title" = "Kexts";
"Kexts_description" = "A collection of useful plist only kexts compatible with Extra";
"AHCIPortInjector_title" = "AHCIPort";
"AHCIPortInjector_description" = "Add AHCI support for Intel Southbridge chipsets ICH6 - ICH10, JMicron JMB383";
"IOAHCIBlockStorageInjector_title" = "IOAHCIBlockStorage";
"IOAHCIBlockStorageInjector_description" = "";
"ATAPortInjector_title" = "IntelPIIXATA";
"ATAPortInjector_description" = "Add ATA support for Intel Southbridge chipsets ICH6 - ICH10";
"JMicronATAInjector_title" = "JMicronATA";
"JMicronATAInjector_description" = "Add JMIcronATA support for Intel chipset";
"Disabler_title" = "Disabler";
"Disabler_description" = "Disable AppleIntelCPUPowerManagement.";
// Error strings
"ERROR_BOOTVOL" = "This software must be installed on the startup volume.";
"ERROR_INSTALL" = "This volume does not meet the requirements for this update.";
"Newer_Package_Installed_message" = "A newer version of Chameleon is already installed";
"Intel_Mac_message" = "This software cannot be installed on this computer.";
branches/azimutz/trunkAutoResolution/package/Resources/Russian.lproj/Welcome.rtfd/TXT.rtf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
{\colortbl;\red255\green255\blue255;\red65\green78\blue255;}
\margl1440\margr1440\vieww11660\viewh12980\viewkind0
\pard\ri0\qc
\f0\b\fs72 \cf0 Chameleon
\fs50 \
\fs26 v%CHAMELEONVERSION% r%CHAMELEONREVISION%
\fs50 \
\
\cf2 %CHAMELEONSTAGE%
\fs26 \cf0 \
\pard\ri0\ql\qnatural
\cf0 \
\
\
Developers: zef, Turbo, dfe, netkas, mackerintel, fassl, Kabyl, kaitek, iNDi, asereBLN, mozodojo, meklort, AzimutZ, Slice\
\
\
Thanks to : JrCs, mercurysquad, munky, rekursor, cosmolt, kalyway, Krazubu, THeKiNG, XyZ, blackosx, DHP, cparm\
\pard\tx360\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\b0\fs30 \cf0 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\fs26 \cf0 Copyright \'a9 2011}
branches/azimutz/trunkAutoResolution/package/Resources/Russian.lproj/Conclusion.rtfd/TXT.rtf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
{\colortbl;\red255\green255\blue255;\red65\green78\blue255;\red255\green0\blue0;}
\margl1440\margr1440\vieww11660\viewh12980\viewkind0
\pard\ri0\qc
\f0\b\fs72 \cf0 Chameleon
\fs50 \
\fs26 v%CHAMELEONVERSION% r%CHAMELEONREVISION%
\fs50 \
\
\cf2 %CHAMELEONSTAGE%\cf0 \
\pard\ri0\ql\qnatural
\fs26 \cf0 \
\pard\ri0\qc
\fs50 \cf3 \uc0\u1059 \u1089 \u1090 \u1072 \u1085 \u1086 \u1074 \u1082 \u1072 \u1074 \u1099 \u1087 \u1086 \u1083 \u1085 \u1077 \u1085 \u1072 !
\b0\fs26 \cf0 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\fs18 \cf0 \
{\field{\*\fldinst{HYPERLINK "http://chameleon.osx86.hu/"}}{\fldrslt
\fs26 http://www.applelife.ru/topic/23967-%d0%bd%d0%be%d0%b2%d1%8b%d0%b9-%d1%85%d0%b0%d0%bc%d0%b5%d0%bb%d0%b5%d0%be%d0%bd/}}
\fs26 \
{\field{\*\fldinst{HYPERLINK "http://forum.voodooprojects.org/index.php"}}{\fldrslt http://forum.voodooprojects.org/index.php}}
\b \
\pard\tx360\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\b0\fs30 \cf0 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\fs26 \cf0 Copyright \'a9 2011}
branches/azimutz/trunkAutoResolution/package/Resources/Russian.lproj/License.rtf
1
2
3
4
5
6
7
8
9
10
11
12
13
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
{\colortbl;\red255\green255\blue255;}
\vieww22060\viewh14020\viewkind0
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\b\fs20 \cf0 \uc0\u1056 \u1091 \u1089 \u1089 \u1082 \u1080 \u1081 \
\
\uc0\u1051 \u1080 \u1094 \u1077 \u1085 \u1079 \u1080 \u1103 \u1085 \u1072 \u1061 \u1072 \u1084 \u1077 \u1083 \u1077 \u1086 \u1085 \u1087 \u1086 \u1076 \u1088 \u1072 \u1079 \u1091 \u1084 \u1077 \u1074 \u1072 \u1077 \u1090 , \u1095 \u1090 \u1086 \u1085 \u1080 \u1082 \u1090 \u1086 \u1085 \u1080 \u1079 \u1072 \u1095 \u1090 \u1086 \
\uc0\u1085 \u1077 \u1086 \u1090 \u1074 \u1077 \u1095 \u1072 \u1077 \u1090 . \u1048 \u1089 \u1087 \u1086 \u1083 \u1100 \u1079 \u1091 \u1081 \u1090 \u1077 \u1085 \u1072 \u1089 \u1074 \u1086 \u1081 \u1089 \u1090 \u1088 \u1072 \u1093 \u1080 \u1088 \u1080 \u1089 \u1082 .\
\b0 \
Rev. 18/07/2011}
branches/azimutz/trunkAutoResolution/package/buildpkg.sh
4848
4949
5050
51
51
5252
5353
5454
......
8888
8989
9090
91
91
9292
9393
9494
cp -f ${1%/*}/i386/cdboot ${1}/Core/Root/usr/standalone/i386
cp -f ${1%/*}/i386/chain0 ${1}/Core/Root/usr/standalone/i386
fixperms "${1}/Core/Root/"
cp -f ${pkgroot}/fdisk ${1}/Core/Root/usr/sbin
cp -f ${pkgroot}/fdisk440 ${1}/Core/Root/usr/sbin/fdisk
local coresize=$( du -hkc "${1}/Core/Root" | tail -n1 | awk {'print $1'} )
buildpackage "${1}/Core" "/" "0" "start_visible=\"false\" start_selected=\"true\""
mkdir -p "${1}/${options[$i]##*/}/Root"
mkdir -p "${1}/${options[$i]##*/}/Scripts"
ditto --noextattr --noqtn "${options[$i]}/postinstall" "${1}/${options[$i]##*/}/Scripts/postinstall"
ditto --noextattr --noqtn "${options[$i]}/postinstall.sh" "${1}/${options[$i]##*/}/Scripts/postinstall.sh"
buildpackage "${1}/${options[$i]##*/}" "/" "" "start_selected=\"false\""
done
branches/azimutz/trunkAutoResolution/CREDITS
33
44
55
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
6
237
248
259
26
27
28
29
30
31
32
33
34
35
36
37
38
10
11
Developers:
----------
Crazor
Dense
fassl
iNDi
JrCs
Kabyl
kaitek
mackerintel
mercurysquad
munky
meklort
mozodojo
rekursor
Turbo
valv
zef
cparm
zef, Turbo, dfe, netkas, mackerintel, fassl, Kabyl, kaitek, iNDi, asereBLN, mozodojo, meklort, AzimutZ, Slice
Thanks to:
---------
asereBLN
Azimutz
bumby
cosmo1t
dfe
Galaxy
kalyway
Krazubu
MasterChief
netkas
sckevyn
smith@@
THeKiNG
JrCs, mercurysquad, munky, rekursor, cosmolt, kalyway, Krazubu, THeKiNG, XyZ, blackosx, DHP, cparm
branches/azimutz/trunkAutoResolution/BLOCKERS
1
21
32
43
54
65
76
8
97
108
119
10
11
12
13
Memory Allocation Error on boot1 loading /boot: http://forge.voodooprojects.org/p/chameleon/issues/101/
Nvidia GT 540M && 310M : can't find rom to patch : http://forge.voodooprojects.org/p/chameleon/issues/99/
** This is also http://forge.voodooprojects.org/p/chameleon/issues/48/
** GT 440 --> http://forge.voodooprojects.org/p/chameleon/issues/98/
Extra Kext Loading dependency error: http://forge.voodooprojects.org/p/chameleon/issues/94/
AMD reported issues in cpu.c http://forge.voodooprojects.org/p/chameleon/issues/92/
Make Package: http://forge.voodooprojects.org/p/chameleon/issues/82/
SMBus : http://forge.voodooprojects.org/p/chameleon/issues/10/
=== Done ===
Multi Booting: http://forge.voodooprojects.org/p/chameleon/issues/62/
Memory Allocation Error on boot1 loading /boot: http://forge.voodooprojects.org/p/chameleon/issues/101/
== Closed ==
SMBus : http://forge.voodooprojects.org/p/chameleon/issues/10/
branches/azimutz/trunkAutoResolution/doc/BootHelp.txt
7272
7373
7474
75
75
76
7677
7778
7879
ignore /E/E and /S/L/E/Extensions.mkext.
GraphicsEnabler=Yes|No Automatic device-properties generation for gfx cards.
AtiConfig=<cardcfg> Use a different card config
AtiConfig=<cardcfg> Use a different card config, e.g. AtiConfig=Megalodon.
AtiPorts=<value> Specify the number of ports, e.g. AtiPorts=2.
UseAtiROM=Yes|No Use an alternate Ati ROM image
(path: /Extra/<vendorid>_<devid>_<subsysid>.rom)
UseNvidiaROM=Yes|No Use an alternate Nvidia ROM image
branches/azimutz/trunkAutoResolution/CHANGES
1
2
3
4
5
16
27
38
- Added AtiPorts option to GraphicsEnabler, so users can override the default number of ports. It proved
to be useful when used to limit the number of ports that a framebuffer registers, which seems to be a
requirement on laptops that can only use 2 ports at the same time.
Thanks to Akbar for testing and AniV also for the tip:
http://forum.voodooprojects.org/index.php/topic,1959.msg10402.html#msg10402
- Added NVidia ION AHCI controllers dev id to AHCIPortInjector kext.
Forgot to mention source on the commit: http://forum.voodooprojects.org/index.php/topic,1170.0.html
- Renamed com.apple.Boot.plist to org.chameleon.Boot.plist.
branches/azimutz/trunkAutoResolution/Makefile
44
55
66
7
87
98
109
......
1413
1514
1615
17
18
16
17
1918
2019
2120
21
2222
23
24
25
26
2327
2428
2529
......
8993
9094
9195
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
92137
93138
94139
......
99144
100145
101146
147
148
149
SYMROOT = $(SRCROOT)/sym
DSTROOT = $(SRCROOT)/dst
DOCROOT = $(SRCROOT)/doc
IMGROOT = $(SRCROOT)/sym/cache
IMGSKELROOT = $(SRCROOT)/imgskel
CDBOOT = ${IMGROOT}/usr/standalone/i386/cdboot
THEME = default
VERSION = `cat version`
REVISION = `cat revision`
VERSION = `cat ${SRCROOT}/version`
REVISION = `cat ${SRCROOT}/revision`
PRODUCT = Chameleon-$(VERSION)-r$(REVISION)
CDLABEL = ${PRODUCT}
ISOIMAGE = ${SYMROOT}/${CDLABEL}.iso
DISTFILE = ${SYMROOT}/${PRODUCT}
IMGROOT = $(SRCROOT)/sym/${PRODUCT}
DISTROOT= ./${PRODUCT}
EXCLUDE = --exclude=.svn --exclude=.DS_Store --exclude=sym --exclude=obj \
--exclude=package --exclude=archive --exclude=User_Guide_src --exclude=*.sh
fi; \
done
dist image: all
@echo "================= Distrib ================="
@echo "\t[RM] ${IMGROOT}"
@rm -rf ${IMGROOT}
@echo "\t[MKDIR] ${IMGROOT}/usr/standalone/i386"
@mkdir -p ${IMGROOT}/usr/standalone/i386
@echo "\t[MKDIR] ${IMGROOT}/Extra/modules"
@mkdir -p ${IMGROOT}/Extra/modules
@echo "\t[MKDIR] ${IMGROOT}/Extra/Themes/Default"
@mkdir -p ${IMGROOT}/Extra/Themes/Default
@echo "\t[MKDIR] ${IMGROOT}/usr/bin"
@mkdir -p ${IMGROOT}/usr/bin
@if [ -e "$(IMGSKELROOT)" ]; then\
@echo "\t[CP] ${IMGROOTSKEL} ${IMGROOT}"\
@cp -R -f "${IMGSKELROOT}"/* "${IMGROOT}";\
fi;
@cp -f ${SYMROOT}/i386/cdboot ${CDBOOT}
@cp -f ${SYMROOT}/i386/modules/* ${IMGROOT}/Extra/modules
@cp -f ${SRCROOT}/artwork/themes/default/* ${IMGROOT}/Extra/Themes/Default
@cp -f ${SYMROOT}/i386/boot ${IMGROOT}/usr/standalone/i386
@cp -f ${SYMROOT}/i386/boot0 ${IMGROOT}/usr/standalone/i386
@cp -f ${SYMROOT}/i386/boot0hfs ${IMGROOT}/usr/standalone/i386
@cp -f ${SYMROOT}/i386/boot0md ${IMGROOT}/usr/standalone/i386
@cp -f ${SYMROOT}/i386/boot1h ${IMGROOT}/usr/standalone/i386
@cp -f ${SYMROOT}/i386/boot1f32 ${IMGROOT}/usr/standalone/i386
@cp -f ${SYMROOT}/i386/fdisk440 ${IMGROOT}/usr/bin
@cp -f ${SYMROOT}/i386/bdmesg ${IMGROOT}/usr/bin
@echo "\t[HDIUTIL] ${ISOIMAGE}"
@hdiutil makehybrid -iso -joliet -hfs -hfs-volume-name \
${CDLABEL} -eltorito-boot ${CDBOOT} -no-emul-boot -ov -o \
"${ISOIMAGE}" ${IMGROOT} -quiet
@echo "\t[GZ] ${DISTFILE}.tar.gz"
@rm -f ${DISTFILE}.tar.gz
@cd ${SYMROOT} && tar -cf ${DISTFILE}.tar ${DISTROOT}
@gzip --best ${DISTFILE}.tar
pkg installer: all
@# TODO: remove sudo
sudo ${SRCROOT}/package/buildpkg.sh ${SYMROOT}/package;
$(SYMROOT)/i386/vers.h: version
@echo "#define I386BOOT_VERSION \"5.0.132\"" > $@
@echo "#define I386BOOT_BUILDDATE \"`date \"+%Y-%m-%d %H:%M:%S\"`\"" >> $@
.PHONY: $(SYMROOT)/i386/vers.h
.PHONY: config
.PHONY: clean
.PHONY: image
.PHONY: pkg
.PHONY: installer

Archive Download the corresponding diff file

Revision: 1251