UINT32 FixPIC (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j, k;
UINT32 IOADR = 0;
UINT32 RESADR = 0;
UINT32 adr = 0;
INT32 offset = 0, sizeoffset = 0;
UINT32 PICADR, picsize = 0;
DBG("Start PIC Fix\n");
for (j=20; j<len; j++) {
// Find Device PIC or IPIC PNP0000
if (CmpPNP(dsdt, j, 0x0000)) {
PICADR = devFind(dsdt, j);
adr = PICADR;
if (!adr) {
continue;
}
picsize = get_size(dsdt, adr);
DBG("PIC size=%x at %x\n", picsize, adr);
if (picsize) {
break;
}
} // End PIC
}
if (!picsize) {
DBG("IPIC not found\n");
return len;
}
for (i=adr; i<adr+picsize; i++)
{
if (dsdt[i] == 0x11 && dsdt[i+2] == 0x0A) {
RESADR = i+1; //Format 11, size, 0A, size-3,... 79, 00
IOADR = i+3; //IO (Decode16 ==> 47, 01
continue;
} else {
// or 11 41 09 0A 8D 47 01 20 00 -> size=0x91 size-4=0x89
if ((dsdt[i] == 0x11) &&
(dsdt[i+3] == 0x0A) &&
((dsdt[i+1] & 0xF0) == 0x40)) {
RESADR = i+1; //Format 11, size1, size2, 0A, size-4,... 79, 00
IOADR = i+4; //IO (Decode16 ==> 47, 01
DBG("found CRS at %x size %x\n", RESADR, dsdt[IOADR]);
continue;
}
}
if (dsdt[i] == 0x22) { // Had IRQNoFlag
for (k = i; k < RESADR + dsdt[IOADR] + 4; k++) {
if ((dsdt[k] == 0x79) ||
((dsdt[k] == 0x47) && (dsdt[k+1] == 0x01)) ||
((dsdt[k] == 0x86) && (dsdt[k+1] == 0x09))) {
sizeoffset = i - k;
DBG("found PIC had IRQNoFlag will move %d bytes\n", sizeoffset);
// First move offset byte remove IRQNoFlag
len = move_data(i, dsdt, len, sizeoffset);
// Fix IO (Decode16, size and _CRS size
// dsdt[RESADR] += (UINT8)sizeoffset;
dsdt[IOADR] += (UINT8)sizeoffset;
offset = write_size(RESADR, dsdt, len, sizeoffset);
sizeoffset += offset;
len += offset;
break;
}
}
}
// if offset > 0 Fix Device PIC size
if (sizeoffset != 0 ) {
offset = write_size(adr, dsdt, len, sizeoffset);
sizeoffset += offset;
DBG("Fix Device PIC size %d\n", sizeoffset);
len += offset;
len = CorrectOuters(dsdt, len, adr-3, sizeoffset);
sizeoffset = 0;
} // sizeoffset if
if ((dsdt[i+1] == 0x5B) && (dsdt[i+2] == 0x82)) {
break; //end of PIC device and begin of new Device()
}
} // i loop
return len;
}