Chameleon

Chameleon Commit Details

Date:2011-07-13 10:51:11 (12 years 8 months ago)
Author:Azimutz
Commit:1158
Parents: 1157
Message:Match nvidia.c with the one on my branch (Chazi) adding dev id's from issue 99 and Asus G74SX (0DF4, 1251).
Changes:
M/trunk/i386/libsaio/nvidia.c
M/trunk/i386/libsaio/ati.c

File differences

trunk/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;
}
trunk/i386/libsaio/ati.c
55
66
77
8
9
108
119
1210
*
*/
#include "libsa.h"
#include "saio_internal.h"
#include "boot.h"
#include "bootstruct.h"
#include "pci.h"

Archive Download the corresponding diff file

Revision: 1158