Chameleon

Chameleon Commit Details

Date:2015-01-26 00:49:01 (9 years 2 months ago)
Author:ErmaC
Commit:2556
Parents: 2555
Message:Refactor function patch_nvidia_rom (Credits Clover Team)
Changes:
M/trunk/i386/libsaio/nvidia.c

File differences

trunk/i386/libsaio/nvidia.c
15671567
15681568
15691569
1570
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
15711590
1572
1591
15731592
15741593
1575
1576
1577
1578
1579
15801594
1581
1595
15821596
1583
1584
1597
1598
1599
15851600
15861601
15871602
1588
1603
1604
1605
15891606
1590
1591
1592
1593
1594
1595
1596
1607
1608
1609
1610
1611
15971612
15981613
1599
1600
1601
1602
1614
1615
1616
1617
1618
16031619
1604
1605
1606
1620
1621
1622
1623
1624
16071625
16081626
16091627
1610
1611
1628
1629
1630
16121631
16131632
1614
1615
1633
1634
1635
16161636
16171637
1638
16181639
16191640
1620
1621
1641
1642
1643
16221644
16231645
1624
1625
1646
1647
1648
1649
16261650
16271651
16281652
1629
1653
1654
16301655
16311656
16321657
1633
1634
1635
1636
1637
1638
1639
1640
1641
1658
1659
16421660
1643
1661
16441662
16451663
1646
1664
1665
16471666
16481667
1649
1668
1669
16501670
16511671
1652
1672
1673
16531674
16541675
16551676
......
16581679
16591680
16601681
1661
1662
1663
16641682
1665
1666
1683
1684
1685
1686
16671687
1668
1669
1688
1689
16701690
16711691
16721692
16731693
16741694
1675
1676
1677
1695
1696
1697
1698
1699
1700
16781701
16791702
16801703
1681
1704
16821705
16831706
1684
1707
1708
1709
16851710
16861711
1687
1688
1689
1712
1713
1714
1715
1716
1717
16901718
16911719
16921720
16931721
16941722
1695
1696
1723
1724
1725
1726
16971727
1698
1699
1728
1729
17001730
17011731
1702
1703
1732
1733
1734
17041735
17051736
17061737
1707
1708
1709
1738
1739
1740
1741
17101742
17111743
17121744
17131745
17141746
1715
1716
1747
1748
17171749
17181750
17191751
1720
1752
17211753
17221754
17231755
1724
1725
1756
1757
1758
17261759
17271760
17281761
......
17381771
17391772
17401773
1741
1742
1774
17431775
1744
1745
1746
1747
1776
1777
1778
1779
1780
1781
1782
17481783
17491784
17501785
17511786
17521787
17531788
1754
1789
1790
17551791
17561792
17571793
......
19241960
19251961
19261962
1927
1963
1964
19281965
19291966
19301967
......
19912028
19922029
19932030
1994
2031
2032
19952033
19962034
1997
2035
19982036
19992037
20002038
20012039
2002
2040
20032041
20042042
20052043
......
20092047
20102048
20112049
2012
2050
20132051
20142052
20152053
2016
2054
2055
2056
2057
20172058
20182059
20192060
20202061
20212062
2022
2023
2063
2064
20242065
20252066
2026
2027
2028
2067
2068
2069
20292070
20302071
2031
2072
20322073
20332074
20342075
20352076
20362077
2037
2078
20382079
20392080
20402081
......
21592200
21602201
21612202
2203
21622204
21632205
21642206
......
23132355
23142356
23152357
2316
2317
23182358
2319
2320
23212359
23222360
23232361
static int patch_nvidia_rom(uint8_t *rom)
{
if (!rom)
uint8_tnum_outputs= 0;
uint8_ti= 0;
uint8_tdcbtable_version;
uint8_theaderlength= 0;
uint8_tnumentries= 0;
uint8_trecordlength= 0;
uint8_tchannel1= 0;
uint8_tchannel2= 0;
uint16_tdcbptr;
uint8_t*dcbtable;
uint8_t*togroup;
inthas_lvds= false;
struct dcbentry {
uint8_t type;
uint8_t index;
uint8_t *heads;
} entries[MAX_NUM_DCB_ENTRIES];
DBG("patch_nvidia_rom.\n");
if (!rom || (rom[0] != 0x55 && rom[1] != 0xaa))
{
printf("ROM not found\n");
DBG("False ROM signature: 0x%02x%02x\n", rom[0], rom[1]);
return PATCH_ROM_FAILED;
}
if (rom[0] != 0x55 && rom[1] != 0xaa)
{
printf("False ROM signature: 0x%02x%02x\n", rom[0], rom[1]);
return PATCH_ROM_FAILED;
}
uint16_t dcbptr = READ_LE_SHORT(rom, 0x36);
dcbptr = *(uint16_t *)&rom[0x36];
if (!dcbptr) {
printf("no dcb table found\n");
if (!dcbptr)
{
DBG("no dcb table found\n");
return PATCH_ROM_FAILED;
}
//else
//printf("dcb table at offset 0x%04x\n", dcbptr);
//{
//DBG("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 numentries = 0;
uint8_t recordlength = 0;
if (dcbtable_version >= 0x20) {
dcbtable= &rom[dcbptr];
dcbtable_version= dcbtable[0];
if (dcbtable_version >= 0x20)
{
uint32_t sig;
if (dcbtable_version >= 0x30) {
headerlength = dcbtable[1];
numentries = dcbtable[2];
recordlength = dcbtable[3];
if (dcbtable_version >= 0x30)
{
headerlength= dcbtable[1];
numentries= dcbtable[2];
recordlength= dcbtable[3];
sig = READ_LE_INT(dcbtable, 6);
} else {
sig = READ_LE_INT(dcbtable, 4);
sig = *(uint32_t *)&dcbtable[6];
}
else
{
sig = *(uint32_t *)&dcbtable[4];
headerlength = 8;
}
if (sig != 0x4edcbdcb) {
printf("Bad display config block signature (0x%8x)\n", sig); //Azi: issue #48
if (sig != 0x4edcbdcb)
{
DBG("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+ */
char sig[8] = { 0 };
}
else if (dcbtable_version >= 0x14) { /* some NV15/16, and NV11+ */
char sig[8];
strncpy(sig, (char *)&dcbtable[-7], 7);
sig[7] = 0;
recordlength = 10;
if (strcmp(sig, "DEV_REC")) {
printf("Bad Display Configuration Block signature (%s)\n", sig);
if (strcmp(sig, "DEV_REC"))
{
DBG("Bad Display Configuration Block signature (%s)\n", sig);
return PATCH_ROM_FAILED;
}
} else {
printf("ERROR: dcbtable_version is 0x%X\n", dcbtable_version);
}
else
{
DBG("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 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 = READ_LE_INT(dcbtable,headerlength + recordlength * i);
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 */
if ((connection & 0x0000000f) == 0x0000000f) /* end of records */
{
continue;
}
if (connection == 0x00000000) { /* seen on an NV11 with DCB v1.5 */
if (connection == 0x00000000) /* seen on an NV11 with DCB v1.5 */
{
continue;
}
if ((connection & 0xf) == 0x6) { /* we skip type 6 as it doesnt appear on macbook nvcaps */
if ((connection & 0xf) == 0x6) /* we skip type 6 as it doesnt appear on macbook nvcaps */
{
continue;
}
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);
//DBG("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);
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);
//DBG("group channel 1\n");
channel1 |= ( 0x1 << entries[i].index );
entries[i].type = TYPE_GROUPED;
if (entries[i-1].type == 0x0) {
channel1 |= ( 0x1 << entries[i-1].index);
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) ) {
//printf("group tv1\n");
channel1 |= ( 0x1 << entries[i+1].index);
if ( ((i+1) < num_outputs) && (entries[i+1].type == 0x1) )
{
//DBG("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);
//DBG("group channel 2 : %d\n", i);
channel2 |= ( 0x1 << entries[i].index );
entries[i].type = TYPE_GROUPED;
if (entries[i - 1].type == 0x0) {
channel2 |= ( 0x1 << entries[i-1].index);
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) ) {
//printf("group tv2\n");
if ( ((i+1) < num_outputs) && (entries[i+1].type == 0x1) )
{
//DBG("group tv2\n");
channel2 |= ( 0x1 << entries[i+1].index);
entries[i+1].type = TYPE_GROUPED;
}
}
// if we have left ungrouped outputs merge them to the empty channel
uint8_t *togroup;// = (channel1 ? (channel2 ? NULL : &channel2) : &channel1);
togroup = &channel2;
togroup = &channel2; // = (channel1 ? (channel2 ? NULL : &channel2) : &channel1);
for (i = 0; i < num_outputs; i++) {
if (entries[i].type != TYPE_GROUPED) {
//printf("%d not grouped\n", i);
if (togroup) {
for (i = 0; i < num_outputs; i++)
{
if (entries[i].type != TYPE_GROUPED)
{
//DBG("%d not grouped\n", i);
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;
unsigned long long mem_detect(volatile uint8_t *regs, uint8_t nvCardType, pci_dt_t *nvda_dev, uint32_t device_id, uint32_t subsys_id)
{
unsigned long long vram_size = 0;
uint64_t vram_size = 0;
// unsigned long long vram_size = 0;
// First check if any value exist in the plist
cardList_t * nvcard = FindCardWithIds(device_id, subsys_id);
}
if (!vram_size)
{ // Finally, if vram_size still not set do the calculation with our own method
{
// Finally, if vram_size still not set do the calculation with our own method
if (nvCardType < NV_ARCH_50)
{
vram_size = REG32(NV04_PFB_FIFO_DATA);
vram_size = (uint64_t)(REG32(NV04_PFB_FIFO_DATA));
vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
}
else if (nvCardType < NV_ARCH_C0)
{
vram_size = REG32(NV04_PFB_FIFO_DATA);
vram_size = (uint64_t)(REG32(NV04_PFB_FIFO_DATA));
vram_size |= (vram_size & 0xff) << 32;
vram_size &= 0xffffffff00ll;
}
vram_size *= REG32(NVC0_MEM_CTRLR_COUNT);
}
}
DBG("mem_detected %ld\n", vram_size);
return vram_size;
}
static bool checkNvRomSig(uint8_t * aRom){
static uint8_t connector_type_1[]= {0x00, 0x08, 0x00, 0x00};
static bool checkNvRomSig(uint8_t * aRom)
{
return aRom != NULL && (aRom[0] == 0x55 && aRom[1] == 0xaa);
}
bool setup_nvidia_devprop(pci_dt_t *nvda_dev)
{
struct DevPropDevice*device = NULL;
char*devicepath = NULL;
struct DevPropDevice*device= NULL;
char*devicepath= NULL;
option_rom_pci_header_t*rom_pci_header;
volatile uint8_t*regs;
uint8_t*rom = NULL;
uint8_tnvCardType = 0;
unsigned long longvideoRam = 0;
uint8_t*rom= NULL;
uint8_tnvCardType= 0;
uint64_tvideoRam= 0;
uint32_tnvBiosOveride;
uint32_tbar[7];
uint32_tboot_display = 0;
uint32_tboot_display= 0;
intnvPatch = 0;
intlen;
charbiosVersion[64];
charnvFilename[64];
charkNVCAP[12];
char*model = NULL;
char*model= NULL;
const char*value;
fill_card_list();
{
string = devprop_create_string();
}
device = devprop_add_device(string, devicepath);
/* FIXME: for primary graphics card only */
//http://forge.voodooprojects.org/p/chameleon/issues/67/
if(getBoolForKey(kEnableHDMIAudio, &doit, &bootInfo->chameleonConfig) && doit)
{
static uint8_t connector_type_1[]= {0x00, 0x08, 0x00, 0x00};
//devprop_add_value(device, "@0,connector-type",connector_type_1, 4);
devprop_add_value(device, "@1,connector-type",connector_type_1, 4);
//devprop_add_value(device, "@2,connector-type",connector_type_1, 4);
//devprop_add_value(device, "@3,connector-type",connector_type_1, 4);
}
/************************ End Audio *************************/

Archive Download the corresponding diff file

Revision: 2556