CloverBootloader/rEFIt_UEFI/Platform/FixBiosDsdt.c
Florin9doi d5021f3f04 Modify PatchACPI to assign processorIDs from DSDT
macOS assumes that the first processor from DSDT is always enabled, without checking MADT table
here we're trying to assign first IDs found in DSDT to enabled processors in MADT, such that macOS assumption to be true
2019-09-14 16:57:54 +03:00

5587 lines
167 KiB
C

/*
* Copyright (c) 2011-2012 Frank Peng. All rights reserved.
*
*/
//totally rebuilt by Slice, 2012-2013
// NForce additions by Oscar09, 2013
#include "StateGenerator.h"
#include <IndustryStandard/PciCommand.h>
#ifdef DBG
#undef DBG
#endif
#ifndef DEBUG_FIX
#ifndef DEBUG_ALL
#define DEBUG_FIX 0
#else
#define DEBUG_FIX DEBUG_ALL
#endif
#endif
#if DEBUG_FIX==0
#define DBG(...)
#else
#define DBG(...) DebugLog(DEBUG_FIX, __VA_ARGS__)
#endif
OPER_REGION *gRegions = NULL;
CHAR8* device_name[12]; // 0=>Display 1=>network 2=>firewire 3=>LPCB 4=>HDAAudio 5=>RTC 6=>TMR 7=>SBUS 8=>PIC 9=>Airport 10=>XHCI 11=>HDMI
CHAR8* UsbName[10];
BOOLEAN HDAFIX = TRUE;
BOOLEAN GFXHDAFIX = TRUE;
BOOLEAN DisplayName1;
BOOLEAN DisplayName2;
BOOLEAN NetworkName;
BOOLEAN ArptName;
BOOLEAN XhciName;
BOOLEAN ArptBCM;
BOOLEAN ArptAtheros;
BOOLEAN LPCBFIX;
BOOLEAN IDEFIX;
BOOLEAN SATAFIX;
BOOLEAN ASUSFIX;
BOOLEAN USBIntel;
BOOLEAN USBNForce;
BOOLEAN USBIDFIX = TRUE;
//BOOLEAN Display1PCIE;
//BOOLEAN Display2PCIE;
BOOLEAN FirewireName;
// for read computer data
UINT32 DisplayADR1[4];
UINT32 DisplayADR2[4];
UINT32 NetworkADR1[4];
UINT32 NetworkADR2[4];
CHAR8* Netmodel[4];
CHAR8* NetName[4] = { "ETH0", "ETH1", "ETH2", "ETH3" };
UINT32 net_count = 0;
UINT32 ArptADR1;
UINT32 ArptADR2;
UINT32 FirewireADR1;
UINT32 FirewireADR2;
UINT32 SBUSADR1;
UINT32 SBUSADR2;
UINT32 IMEIADR1;
UINT32 IMEIADR2;
UINT32 IDEADR1;
UINT32 IDEADR2;
UINT32 SATAADR1;
UINT32 SATAADR2;
UINT32 SATAAHCIADR1;
UINT32 SATAAHCIADR2;
UINT32 IDEVENDOR;
UINT32 SATAVENDOR;
UINT32 SATAAHCIVENDOR;
UINT32 DisplayVendor[4];
UINT16 DisplayID[4];
UINT32 DisplaySubID[4];
UINT16 ArptDID;
//UINT32 PWRBADR;
UINT32 HDAADR1;
UINT32 HDMIADR1;
UINT32 HDMIADR2;
UINT32 USBADR[12];
UINT32 USBADR2[12];
UINT32 USBADR3[12]; /*<-NFORCE_USB*/
UINT32 USBID[12];
UINT32 USB20[12];
UINT32 USB30[12];
UINT32 USB40[12]; /*<-NFORCE_USB*/
UINT32 HDAcodecId=0;
UINT32 HDAlayoutId=0;
UINT32 GfxcodecId[2] = {0, 1};
UINT32 GfxlayoutId[2] = {1, 12};
pci_dt_t Displaydevice[2];
UINTN usb;
struct lpc_device_t
{
UINT32 id;
};
//static
CHAR8 dataBuiltin[] = {0x00};
//static
CHAR8 dataBuiltin1[] = {0x01};
static struct lpc_device_t lpc_chipset[] =
{
{0x00000000},
//
{0x80862811},
{0x80862815},
{0x808627b9},
{0x808627bd},
{0x80862670},
{0x80868119},
{0x80862916},
{0x80863a18},
{0x80863b00},
{0x80863b01},
{0x80863b02},
{0x80863b09},
{0x10de0aac},
{0x10de0aae},
{0x10de0aaf},
{0x10de0d80},
{0x10de0d81},
{0x10de0d82},
{0x10de0d83},
//SB
{0x80861c42},
{0x80861c44},
{0x80861c4e},
{0x80861c4c},
{0x80861c50},
{0x80861c4a},
{0x80861c46},
{0x80861c5c},
{0x80861c52},
{0x80861c54},
{0x80861c56},
{0x80861c43},
{0x80861c4f},
{0x80861c47},
{0x80861c4b},
{0x80861c49},
{0x80861c41},
{0x80861c4d},
};
struct net_chipsets_t {
UINT32 id;
CHAR8 *name;
};
static struct net_chipsets_t NetChipsets[] = {
{ 0x00000000, "Unknown" },
// 8169
{ 0x10EC8169, "Realtek 8169/8110 Gigabit Ethernet" },
{ 0x10EC8168, "Realtek 8168/8101E Gigabit Ethernet" },
{ 0x10EC8167, "Realtek 8169/8110 Gigabit Ethernet" },
{ 0x10EC8136, "Realtek 8168/8101E Gigabit Ethernet" },
// 8139
{ 0x10EC8139, "Realtek RTL8139/810x Family Fast Ethernet" },
{ 0x11861300, "Realtek RTL8139/810x Family Fast Ethernet" },
{ 0x11131211, "Realtek RTL8139/810x Family Fast Ethernet" },
// Broadcom 57XX
{ 0x14e41600, "Broadcom 5751 Ethernet" },
{ 0x14e41659, "Broadcom 57XX Ethernet" },
{ 0x14e4165A, "BCM5722 NetXtreme Server Gigabit Ethernet" },
{ 0x14e4166A, "Broadcom 57XX Ethernet" },
{ 0x14e41672, "BCM5754M NetXtreme Gigabit Ethernet" },
{ 0x14e41673, "BCM5755M NetXtreme Gigabit Ethernet" },
{ 0x14e4167A, "BCM5754 NetXtreme Gigabit Ethernet" },
{ 0x14e4167B, "BCM5755 NetXtreme Gigabit Ethernet" },
{ 0x14e41684, "Broadcom 57XX Ethernet" },
{ 0x14e41691, "BCM57788 NetLink (TM) Gigabit Ethernet" },
{ 0x14e41693, "BCM5787M NetLink (TM) Gigabit Ethernet" },
{ 0x14e4169B, "BCM5787 NetLink (TM) Gigabit Ethernet" },
{ 0x14e416B4, "Broadcom 57XX Ethernet" },
{ 0x14e416B5, "BCM57785 Gigabit Ethernet PCIe" },
{ 0x14e41712, "BCM5906 NetLink (TM) Fast Ethernet" },
{ 0x14e41713, "BCM5906M NetLink (TM) Fast Ethernet" },
// Intel 8255x Ethernet
{ 0x80861051, "Intel 8255x Ethernet" },
{ 0x80861050, "Intel 8255x Ethernet" },
{ 0x80861029, "Intel 8255x Ethernet" },
{ 0x80861030, "Intel 8255x Ethernet" },
{ 0x80861209, "Intel 8255x Ethernet" },
{ 0x80861227, "Intel 8255x Ethernet" },
{ 0x80861228, "Intel 8255x Ethernet" },
{ 0x80861229, "Intel 8255x Ethernet" },
{ 0x80861503, "Intel 82579V Gigabit Network Controller" },
{ 0x80862449, "Intel 8255x Ethernet" },
{ 0x80862459, "Intel 8255x Ethernet" },
{ 0x8086245D, "Intel 8255x Ethernet" },
{ 0x80861091, "Intel 8255x Ethernet" },
{ 0x80861060, "Intel 8255x Ethernet" },
// Atheros AR8151 Ethernet
{ 0x19691083, "Qualcomm Atheros AR8151 v2.0 Gigabit Ethernet" },
};
struct ide_chipsets_t {
UINT32 id;
};
static struct ide_chipsets_t ide_chipset[] =
{
// IDE
{0x00000000},
//
{0x8086269e},
{0x808627df},
{0x80862850},
//SATA
{0x80862680},
{0x808627c0},
{0x808627c4},
{0x80862828},
};
//2820? 2825?
/*
struct ahci_chipsets_t {
UINT32 id;
};
static struct ahci_chipsets_t ahci_chipset[] =
{
// SATA AHCI
{0x00000000},
//
{0x80863a22},
{0x80862681},
{0x80862682},
{0x808627c5},
{0x80862825},
{0x80862829},
{0x80863b29},
{0x80863b22},
{0x80863b2f},
{0x80861c02},
{0x80861c03},
{0x10de0ab9},
{0x10de0b88},
};
*/
UINT8 dtgp[] = // Method (DTGP, 5, NotSerialized) ......
{
0x14, 0x3F, 0x44, 0x54, 0x47, 0x50, 0x05, 0xA0,
0x30, 0x93, 0x68, 0x11, 0x13, 0x0A, 0x10, 0xC6,
0xB7, 0xB5, 0xA0, 0x18, 0x13, 0x1C, 0x44, 0xB0,
0xC9, 0xFE, 0x69, 0x5E, 0xAF, 0x94, 0x9B, 0xA0,
0x18, 0x93, 0x69, 0x01, 0xA0, 0x0C, 0x93, 0x6A,
0x00, 0x70, 0x11, 0x03, 0x01, 0x03, 0x6C, 0xA4,
0x01, 0xA0, 0x06, 0x93, 0x6A, 0x01, 0xA4, 0x01,
0x70, 0x11, 0x03, 0x01, 0x00, 0x6C, 0xA4, 0x00
};
UINT8 sbus1[] =
{ // Device (SBUS) _ADR,1F0003 size=E9+2=EB
0x5B, 0x82, 0x49, 0x0E, 0x53, 0x42, 0x55, 0x53, // 00000080 "[.I.SBUS"
0x08, 0x5F, 0x41, 0x44, 0x52, 0x0C, // 00000088 "._ADR."
0x03, 0x00, 0x1F, 0x00, 0x5B, 0x82, 0x4B, 0x05, // 00000090 "....[.K."
0x42, 0x55, 0x53, 0x30, 0x08, 0x5F, 0x43, 0x49, // 00000098 "BUS0._CI"
0x44, 0x0D, 0x73, 0x6D, 0x62, 0x75, 0x73, 0x00, // 000000A0 "D.smbus."
0x08, 0x5F, 0x41, 0x44, 0x52, 0x00, 0x5B, 0x82, // 000000A8 "._ADR.[."
0x41, 0x04, 0x44, 0x56, 0x4C, 0x30, 0x08, 0x5F, // 000000B0 "A.DVL0._"
0x41, 0x44, 0x52, 0x0A, 0x57, 0x08, 0x5F, 0x43, // 000000B8 "ADR.W._C"
0x49, 0x44, 0x0D, 0x64, 0x69, 0x61, 0x67, 0x73, // 000000C0 "ID.diags"
0x76, 0x61, 0x75, 0x6C, 0x74, 0x00, 0x14, 0x22, // 000000C8 "vault..""
0x5F, 0x44, 0x53, 0x4D, 0x04, 0x70, 0x12, 0x0D, // 000000D0 "_DSM.p.."
0x02, 0x0D, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, // 000000D8 "..addres"
0x73, 0x00, 0x0A, 0x57, 0x60, 0x44, 0x54, 0x47, // 000000E0 "s..W`DTG"
0x50, 0x68, 0x69, 0x6A, 0x6B, 0x71, 0x60, 0xA4, // 000000E8 "Phijkq`."
0x60, 0x14, 0x4B, 0x07, 0x5F, 0x44, 0x53, 0x4D, // 000000F0 "`.K._DSM"
0x04, 0x70, 0x12, 0x45, 0x06, 0x08, 0x0D, 0x62, // 000000F8 ".p.E...b"
0x75, 0x69, 0x6C, 0x74, 0x2D, 0x69, 0x6E, 0x00, // 00000100 "uilt-in."
0x11, 0x03, 0x01, 0x01, 0x0D, 0x64, 0x65, 0x76, // 00000108 ".....dev"
0x69, 0x63, 0x65, 0x2D, 0x69, 0x64, 0x00, 0x11, // 00000110 "ice-id.."
0x07, 0x0A, 0x04, 0x30, 0x3A, 0x00, 0x00, 0x0D, // 00000118 "...0:..."
0x6D, 0x6F, 0x64, 0x65, 0x6C, 0x00, 0x11, 0x1E, // 00000120 "model..."
0x0A, 0x1B, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x20, // 00000128 "..Intel "
0x38, 0x32, 0x38, 0x30, 0x31, 0x4A, 0x49, 0x20, // 00000130 "82801JI "
0x49, 0x43, 0x48, 0x31, 0x30, 0x20, 0x46, 0x61, // 00000138 "ICH10 Fa"
0x6D, 0x69, 0x6C, 0x79, 0x00, 0x0D, 0x6E, 0x61, // 00000140 "mily..na"
0x6D, 0x65, 0x00, 0x11, 0x14, 0x0A, 0x11, 0x53, // 00000148 "me.....S"
0x4D, 0x42, 0x75, 0x73, 0x20, 0x63, 0x6F, 0x6E, // 00000150 "MBus con"
0x74, 0x72, 0x6F, 0x6C, 0x6C, 0x65, 0x72, 0x00, // 00000158 "troller."
0x60, 0x44, 0x54, 0x47, 0x50, 0x68, 0x69, 0x6A, // 00000160 "`DTGPhij"
0x6B, 0x71, 0x60, 0xA4, 0x60
};
UINT8 bus0[] = {
//size=5B+2=5D
0x5B, 0x82, 0x4B, 0x05, 0x42, 0x55,
0x53, 0x30, 0x08, 0x5F, 0x43, 0x49, 0x44, 0x0D,
0x73, 0x6D, 0x62, 0x75, 0x73, 0x00, 0x08, 0x5F,
0x41, 0x44, 0x52, 0x00, 0x5B, 0x82, 0x41, 0x04,
0x44, 0x56, 0x4C, 0x30, 0x08, 0x5F, 0x41, 0x44,
0x52, 0x0A, 0x57, 0x08, 0x5F, 0x43, 0x49, 0x44,
0x0D, 0x64, 0x69, 0x61, 0x67, 0x73, 0x76, 0x61,
0x75, 0x6C, 0x74, 0x00, 0x14, 0x22, 0x5F, 0x44,
0x53, 0x4D, 0x04, 0x70, 0x12, 0x0D, 0x02, 0x0D,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x00,
0x0A, 0x57, 0x60, 0x44, 0x54, 0x47, 0x50, 0x68,
0x69, 0x6A, 0x6B, 0x71, 0x60, 0xA4, 0x60
};
UINT8 patafix[] = {
/* OperationRegion (IDET, PCI_Config, 0x40, 0x04)
Field (IDET, WordAcc, NoLock, Preserve)
{
M1, 8,
M2, 8,
M3, 8,
M4, 8
}
Method (_INI, 0, NotSerialized)
{
Store (0x07, M1)
Store (0xE3, M2)
Store (Zero, M3)
Store (0xC0, M4)
Return (Zero)
}
*/
0x5B,
0x80, 0x49, 0x44, 0x45, 0x54, 0x02, 0x0A, 0x40, //000001C0 ".IDET..@"
0x0A, 0x04, 0x5B, 0x81, 0x1A, 0x49, 0x44, 0x45, //000001C8 "..[..IDE"
0x54, 0x02, 0x4D, 0x31, 0x5F, 0x5F, 0x08, 0x4D, //000001D0 "T.M1__.M"
0x32, 0x5F, 0x5F, 0x08, 0x4D, 0x33, 0x5F, 0x5F, //000001D8 "2__.M3__"
0x08, 0x4D, 0x34, 0x5F, 0x5F, 0x08, 0x14, 0x23, //000001E0 ".M4__..#"
0x5F, 0x49, 0x4E, 0x49, 0x00, 0x70, 0x0A, 0x07, //000001E8 "_INI.p.."
0x4D, 0x31, 0x5F, 0x5F, 0x70, 0x0A, 0xE3, 0x4D, //000001F0 "M1__p..M"
0x32, 0x5F, 0x5F, 0x70, 0x00, 0x4D, 0x33, 0x5F, //000001F8 "2__p.M3_"
0x5F, 0x70, 0x0A, 0xC0, 0x4D, 0x34, 0x5F, 0x5F, //00000200 "_p..M4__"
0xA4, 0x00 //00000208 ".."
};
UINT8 hpet0[] = {
0x5B, 0x82, 0x3A, 0x48, 0x50, 0x45, 0x54, // Device (HPET)
0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x01, 0x03, // Name (_HID, EisaId ("PNP0103"))
0x08, 0x5F, 0x43, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0C, 0x01, // Name (_CID, EisaId ("PNP0C01"))
0x08, 0x5F, 0x53, 0x54, 0x41, 0x0A, 0x0F, // Name (_STA, 0x0F)
0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x14, 0x0A, 0x11, // Name (_CRS, ResourceTemplate ()
0x22, 0x01, 0x09, 0x86, 0x09, 0x00, 0x01, // IRQNoFlags () {0,8,11}
0x00, 0x00, 0xD0, 0xFE, 0x00, 0x04, 0x00, 0x00, // Memory32Fixed (ReadWrite,
0x79, 0x00 // 0xFED00000, 0x00000400 )
/*
0x5B, 0x82, 0x47, 0x04, 0x48, 0x50, 0x45, 0x54, //Device (HPET)
0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x01, 0x03, //Name (_HID, EisaId ("PNP0103"))
0x08, 0x5F, 0x43, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0C, 0x01, //Name (_CID, EisaId ("PNP0C01"))
0x08, 0x41, 0x54, 0x54, 0x30, 0x11, 0x14, 0x0A, 0x11, //Name (ATT0, ResourceTemplate ()
0x86, 0x09, 0x00, 0x01, // Memory32Fixed (ReadWrite,
0x00, 0x00, 0xD0, 0xFE, 0x00, 0x04, 0x00, 0x00, // 0xFED00000, 0x00000400, )
0x22, 0x01, 0x09, 0x79, 0x00, // IRQNoFlags () {0,8,11}
// 0x14, 0x09, 0x5F, 0x53, 0x54, 0x41, 0x00, //Method (_STA, 0, NotSerialized)
// 0xA4, 0x0A, 0x0F, // Return (0x0F)
0x08, 0x5F, 0x53, 0x54, 0x41, 0x0A, 0x0F, // Name (_STA, 0x0F)
0x14, 0x0B, 0x5F, 0x43, 0x52, 0x53, 0x00, //Method (_CRS, 0, NotSerialized)
0xA4, 0x41, 0x54, 0x54, 0x30 // Return (ATT0)
*/
};
/*
UINT8 hpet1[] = // Name (_CID, EisaId ("PNP0C01"))
{
0x08, 0x5F, 0x43, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0C, 0x01
};
*/
CHAR8 wakret[] = { 0xA4, 0x12, 0x04, 0x02, 0x00, 0x00 };
CHAR8 wakslp1[] = { 0x5B, 0x80, 0x50, 0x4D, 0x33, 0x30, 0x01 };
CHAR8 wakslp2[] = { 0x0A, 0x08, 0x5B, 0x81, 0x0D, 0x50, 0x4D, 0x33, 0x30, 0x01,
0x00, 0x04, 0x53, 0x4C, 0x4D, 0x45, 0x01, 0x70, 0x00, 0x53, 0x4C, 0x4D, 0x45 };
CHAR8 waksecur[] = {0xA0, 0x0D, 0x91, 0x95, 0x68, 0x01, 0x94, 0x68, 0x0A, 0x05,
0x70, 0x0A, 0x03, 0x68};
CHAR8 pwrb[] = { //? \_SB_PWRB, 0x02
0x86, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x57, 0x52, 0x42, 0x0A, 0x02
};
CHAR8 acpi3[] = { //Name(_HID, "ACPI003")
0x08, 0x5F, 0x48, 0x49, 0x44, 0x0D,
0x41, 0x43, 0x50, 0x49, 0x30, 0x30, 0x30, 0x33, 0x00
};
//Name (_PRW, Package (0x02){0x1C, 0x03}
CHAR8 prw1c[] = {
0x08, 0x5F, 0x50, 0x52, 0x57, 0x12, 0x06, 0x02, 0x0A, 0x1C, 0x0A, 0x03
};
CHAR8 dtgp_1[] = { // DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
// Return (Local0)
0x44, 0x54, 0x47, 0x50, 0x68, 0x69, 0x6A, 0x6B,
0x71, 0x60, 0xA4, 0x60
};
CHAR8 pwrbcid[] = {
0x08, 0x5F, 0x43, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0C, 0x0E, 0x14,
0x0E, 0x5F, 0x50, 0x52, 0x57, 0x00, 0xA4, 0x12, 0x06, 0x02, 0x0A,
0x0B, 0x0A, 0x04
};
CHAR8 pwrbprw[] = {
0x14, 0x0E, 0x5F, 0x50, 0x52, 0x57, 0x00, 0xA4, 0x12, 0x06, 0x02,
0x0A, 0x0B, 0x0A, 0x04
};
CHAR8 shutdown0[] = {
0xA0, 0x05, 0x93, 0x68, 0x0A, 0x05, 0xA1, 0x01
};
CHAR8 shutdown1[] = {
0xA0, 0x0F, 0x91, 0x91, 0x93, 0x68, 0x0A, 0x03, 0x93, 0x68, 0x0A, 0x04, 0x93, 0x68, 0x0A, 0x05, 0xA1, 0x01
};
CHAR8 pnlf[] = {
0x5B, 0x82, 0x2D, 0x50, 0x4E, 0x4C, 0x46, //Device (PNLF)
0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x06, 0x10, 0x00, 0x02, // Name (_HID, EisaId ("APP0002"))
0x08, 0x5F, 0x43, 0x49, 0x44, // Name (_CID,
0x0D, 0x62, 0x61, 0x63, 0x6B, 0x6C, 0x69, 0x67, 0x68, 0x74, 0x00, // "backlight")
0x08, 0x5F, 0x55, 0x49, 0x44, 0x0A, 0x0A, // Name (_UID, 0x0A)
0x08, 0x5F, 0x53, 0x54, 0x41, 0x0A, 0x0B // Name (_STA, 0x0B)
};
CHAR8 app2[] = { //Name (_HID, EisaId("APP0002"))
0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x06, 0x10, 0x00, 0x02
};
CHAR8 darwin[] =
{ //addresses shifted by 0x24
0x08, 0x56, 0x45, 0x52, // 00000020 " .. .VER"
0x30, 0x0D, 0x43, 0x6C, 0x6F, 0x76, 0x65, 0x72, // 00000028 "0.Clover"
0x20, 0x61, 0x75, 0x74, 0x6F, 0x70, 0x61, 0x74, // 00000030 " autopat"
0x63, 0x68, 0x65, 0x64, 0x00, 0x08, 0x57, 0x58, // 00000038 "ched..WX"
0x50, 0x31, 0x0D, 0x57, 0x69, 0x6E, 0x64, 0x6F, // 00000040 "P1.Windo"
0x77, 0x73, 0x20, 0x32, 0x30, 0x30, 0x31, 0x00, // 00000048 "ws 2001."
0x14, 0x12, 0x47, 0x45, 0x54, 0x39, 0x02, 0x8C, // 00000050 "..GET9.."
0x68, 0x69, 0x54, 0x43, 0x48, 0x39, 0xA4, 0x54, // 00000058 "hiTCH9.T"
0x43, 0x48, 0x39, 0x14, 0x40, 0x05, 0x53, 0x54, // 00000060 "CH9.@.ST"
0x52, 0x39, 0x02, 0x08, 0x53, 0x54, 0x52, 0x38, // 00000068 "R9..STR8"
0x11, 0x03, 0x0A, 0x50, 0x08, 0x53, 0x54, 0x52, // 00000070 "...P.STR"
0x39, 0x11, 0x03, 0x0A, 0x50, 0x70, 0x68, 0x53, // 00000078 "9...PphS"
0x54, 0x52, 0x38, 0x70, 0x69, 0x53, 0x54, 0x52, // 00000080 "TR8piSTR"
0x39, 0x70, 0x00, 0x60, 0x70, 0x01, 0x61, 0xA2, // 00000088 "9p.`p.a."
0x22, 0x61, 0x70, 0x47, 0x45, 0x54, 0x39, 0x53, // 00000090 ""apGET9S"
0x54, 0x52, 0x38, 0x60, 0x61, 0x70, 0x47, 0x45, // 00000098 "TR8`apGE"
0x54, 0x39, 0x53, 0x54, 0x52, 0x39, 0x60, 0x62, // 000000A0 "T9STR9`b"
0xA0, 0x07, 0x92, 0x93, 0x61, 0x62, 0xA4, 0x00, // 000000A8 "....ab.."
0x75, 0x60, 0xA4, 0x01, 0x14, 0x15, 0x4F, 0x4F, // 000000B0 "u`....OO"
0x53, 0x49, 0x01, 0xA0, 0x0C, 0x53, 0x54, 0x52, // 000000B8 "SI...STR"
0x39, 0x57, 0x58, 0x50, 0x31, 0x68, 0xA4, 0x01, // 000000C0 "9WXP1h.."
0xA4, 0x00 // 000000C8 ".."
};
CHAR8 ClassFix[] = { 0x00, 0x00, 0x03, 0x00 };
BOOLEAN CmpNum(UINT8 *dsdt, INT32 i, BOOLEAN Sure)
{
return ((Sure && ((dsdt[i-1] == 0x0A) ||
(dsdt[i-2] == 0x0B) ||
(dsdt[i-4] == 0x0C))) ||
(!Sure && (((dsdt[i-1] >= 0x0A) && (dsdt[i-1] <= 0x0C)) ||
((dsdt[i-2] == 0x0B) || (dsdt[i-2] == 0x0C)) ||
(dsdt[i-4] == 0x0C))));
}
// for HDA from device_inject.c and mark device_inject function
//extern UINT32 HDA_IC_sendVerb(EFI_PCI_IO_PROTOCOL *PciIo, UINT32 codecAdr, UINT32 nodeId, UINT32 verb);
BOOLEAN get_lpc_model(UINT32 id) {
int i;
for (i=1; i< (sizeof(lpc_chipset) / sizeof(lpc_chipset[0])); i++) {
if (lpc_chipset[i].id == id) {
return FALSE;
}
}
return TRUE;
}
BOOLEAN get_ide_model(UINT32 id) {
int i;
for (i=1; i< (sizeof(ide_chipset) / sizeof(ide_chipset[0])); i++) {
if (ide_chipset[i].id == id) {
return FALSE;
}
}
return TRUE;
}
/*
BOOLEAN get_ahci_model(UINT32 id) {
int i;
for (i=1; i< (sizeof(ahci_chipset) / sizeof(ahci_chipset[0])); i++) {
if (ahci_chipset[i].id == id) {
return FALSE;
}
}
return TRUE;
}
*/
CHAR8* get_net_model(UINT32 id) {
int i;
for (i=1; i< (sizeof(NetChipsets) / sizeof(NetChipsets[0])); i++) {
if (NetChipsets[i].id == id) {
return NetChipsets[i].name;
}
}
return NetChipsets[0].name;
}
VOID GetPciADR(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT UINT32 *Addr1, OUT UINT32 *Addr2, OUT UINT32 *Addr3)
{
PCI_DEVICE_PATH *PciNode;
UINTN PciNodeCount;
EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath = DuplicateDevicePath(DevicePath);
// default to 0
if (Addr1 != NULL) *Addr1 = 0;
if (Addr2 != NULL) *Addr2 = 0xFFFE; //some code we will consider as "non-exists" b/c 0 is meaningful value
// as well as 0xFFFF
if (Addr3 != NULL) *Addr3 = 0xFFFE;
if (!TmpDevicePath) {
return;
}
// sanity check - expecting ACPI path for PciRoot
if (TmpDevicePath->Type != ACPI_DEVICE_PATH && TmpDevicePath->SubType != ACPI_DP) {
FreePool(TmpDevicePath);
return;
}
PciNodeCount = 0;
while (TmpDevicePath && !IsDevicePathEndType(TmpDevicePath)) {
if (TmpDevicePath->Type == HARDWARE_DEVICE_PATH && TmpDevicePath->SubType == HW_PCI_DP) {
PciNodeCount++;
PciNode = (PCI_DEVICE_PATH *)TmpDevicePath;
if (PciNodeCount == 1 && Addr1 != NULL) {
*Addr1 = (PciNode->Device << 16) | PciNode->Function;
} else if (PciNodeCount == 2 && Addr2 != NULL) {
*Addr2 = (PciNode->Device << 16) | PciNode->Function;
} else if (PciNodeCount == 3 && Addr3 != NULL) {
*Addr3 = (PciNode->Device << 16) | PciNode->Function;
} else {
break;
}
}
TmpDevicePath = NextDevicePathNode(TmpDevicePath);
}
return;
}
/* Discussion
Native USB mean for those chipsets IOUSBFamily set some "errata"
for example native 0x1cXX has no such errata */
BOOLEAN NativeUSB(UINT16 DID)
{
UINT16 d = DID & 0xFF00;
return ((d == 0x2600) || (d == 0x2700) || (d == 0x2800) || (d == 0x3a00) || (d == /*NFORCE_USB->*/0x0a00));
}
VOID CheckHardware()
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer = NULL;
EFI_HANDLE Handle;
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
UINTN HandleCount = 0;
UINTN HandleIndex;
UINTN Segment;
UINTN Bus;
UINTN Device;
UINTN Function;
UINTN display=0;
pci_dt_t PCIdevice;
EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
usb=0;
// Scan PCI handles
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiPciIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (!EFI_ERROR (Status)) {
// DBG("PciIo handles count=%d\n", HandleCount);
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
Handle = HandleBuffer[HandleIndex];
Status = gBS->HandleProtocol (
Handle,
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo
);
if (!EFI_ERROR (Status)) {
UINT32 deviceid;
/* Read PCI BUS */
PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint32,
0,
sizeof (Pci) / sizeof (UINT32),
&Pci
);
deviceid = Pci.Hdr.DeviceId | (Pci.Hdr.VendorId << 16);
// add for auto patch dsdt get DSDT Device _ADR
PCIdevice.DeviceHandle = Handle;
DevicePath = DevicePathFromHandle (Handle);
if (DevicePath) {
// DBG("Device patch = %s \n", DevicePathToStr(DevicePath));
//Display ADR
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_DISPLAY) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_DISPLAY_VGA)) {
#if DEBUG_FIX
UINT32 dadr1, dadr2;
#endif
// PCI_IO_DEVICE *PciIoDevice;
GetPciADR(DevicePath, &DisplayADR1[display], &DisplayADR2[display], NULL);
DBG("VideoCard devID=0x%x\n", ((Pci.Hdr.DeviceId << 16) | Pci.Hdr.VendorId));
#if DEBUG_FIX
dadr1 = DisplayADR1[display];
dadr2 = DisplayADR2[display];
DBG("DisplayADR1[%d] = 0x%x, DisplayADR2[%d] = 0x%x\n", display, dadr1, display, dadr2);
#endif
// dadr2 = dadr1; //to avoid warning "unused variable" :(
DisplayVendor[display] = Pci.Hdr.VendorId;
DisplayID[display] = Pci.Hdr.DeviceId;
DisplaySubID[display] = (Pci.Device.SubsystemID << 16) | (Pci.Device.SubsystemVendorID << 0);
// for get display data
Displaydevice[display].DeviceHandle = HandleBuffer[HandleIndex];
Displaydevice[display].dev.addr = (UINT32)PCIADDR(Bus, Device, Function);
Displaydevice[display].vendor_id = Pci.Hdr.VendorId;
Displaydevice[display].device_id = Pci.Hdr.DeviceId;
Displaydevice[display].revision = Pci.Hdr.RevisionID;
Displaydevice[display].subclass = Pci.Hdr.ClassCode[0];
Displaydevice[display].class_id = *((UINT16*)(Pci.Hdr.ClassCode+1));
Displaydevice[display].subsys_id.subsys.vendor_id = Pci.Device.SubsystemVendorID;
Displaydevice[display].subsys_id.subsys.device_id = Pci.Device.SubsystemID;
//
// Detect if PCI Express Device
//
//
// Go through the Capability list
//unused
/* PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
if (PciIoDevice->IsPciExp) {
if (display==0)
Display1PCIE = TRUE;
else
Display2PCIE = TRUE;
}
DBG("Display %d is %aPCIE\n", display, (PciIoDevice->IsPciExp) ? "" :" not"); */
display++;
}
//Network ADR
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_NETWORK) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_NETWORK_ETHERNET)) {
GetPciADR(DevicePath, &NetworkADR1[net_count], &NetworkADR2[net_count], NULL);
// DBG("NetworkADR1 = 0x%x, NetworkADR2 = 0x%x\n", NetworkADR1, NetworkADR2);
// Netmodel = get_net_model(deviceid);
Netmodel[net_count] = get_net_model(deviceid);
net_count++;
}
//Network WiFi ADR
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_NETWORK) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_NETWORK_OTHER)) {
GetPciADR(DevicePath, &ArptADR1, &ArptADR2, NULL);
// DBG("ArptADR1 = 0x%x, ArptADR2 = 0x%x\n", ArptADR1, ArptADR2);
// Netmodel = get_arpt_model(deviceid);
ArptBCM = (Pci.Hdr.VendorId == 0x14e4);
if (ArptBCM) {
DBG("Found Airport BCM at 0x%x, 0x%x\n", ArptADR1, ArptADR2);
}
ArptAtheros = (Pci.Hdr.VendorId == 0x168c);
ArptDID = Pci.Hdr.DeviceId;
if (ArptAtheros) {
DBG("Found Airport Atheros at 0x%x, 0x%x, DeviceID=0x%04x\n", ArptADR1, ArptADR2, ArptDID);
}
}
//Firewire ADR
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_SERIAL) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_SERIAL_FIREWIRE)) {
GetPciADR(DevicePath, &FirewireADR1, &FirewireADR2, NULL);
// DBG("FirewireADR1 = 0x%x, FirewireADR2 = 0x%x\n", FirewireADR1, FirewireADR2);
}
//SBUS ADR
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_SERIAL) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_SERIAL_SMB)) {
GetPciADR(DevicePath, &SBUSADR1, &SBUSADR2, NULL);
// DBG("SBUSADR1 = 0x%x, SBUSADR2 = 0x%x\n", SBUSADR1, SBUSADR2);
}
//IMEI ADR
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_SCC) &&
(Pci.Hdr.ClassCode[1] == PCI_SUBCLASS_SCC_OTHER)) {
GetPciADR(DevicePath, &IMEIADR1, &IMEIADR2, NULL);
}
//USB
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_SERIAL) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_SERIAL_USB) &&
(Pci.Hdr.ClassCode[0] != 0xFE)) {
UINT16 DID = Pci.Hdr.DeviceId;
USBIntel = (Pci.Hdr.VendorId == 0x8086);
USBNForce = (Pci.Hdr.VendorId == 0x10de);
GetPciADR(DevicePath, &USBADR[usb], &USBADR2[usb], &USBADR3[usb]);
DBG("USBADR[%d] = 0x%x and PCIe = 0x%x\n", usb, USBADR[usb], USBADR2[usb]);
if (USBIDFIX)
{
if (USBADR[usb] == 0x001D0000 && !NativeUSB(DID)) DID = 0x3a34;
if (USBADR[usb] == 0x001D0001 && !NativeUSB(DID)) DID = 0x3a35;
if (USBADR[usb] == 0x001D0002 && !NativeUSB(DID)) DID = 0x3a36;
if (USBADR[usb] == 0x001D0003 && !NativeUSB(DID)) DID = 0x3a37;
if (USBADR[usb] == 0x001A0000 && !NativeUSB(DID)) DID = 0x3a37;
if (USBADR[usb] == 0x001A0001 && !NativeUSB(DID)) DID = 0x3a38;
if (USBADR[usb] == 0x001A0002 && !NativeUSB(DID)) DID = 0x3a39;
if (USBADR[usb] == 0x001D0007 && !NativeUSB(DID)) DID = 0x3a3a;
if (USBADR[usb] == 0x001A0007 && !NativeUSB(DID)) DID = 0x3a3c;
//NFORCE_USB_START
if (USBADR3[usb] == 0x00040000 && !NativeUSB(DID)) DID = 0x0aa5;
if (USBADR3[usb] == 0x00040001 && !NativeUSB(DID)) DID = 0x0aa6;
if (USBADR3[usb] == 0x00060000 && !NativeUSB(DID)) DID = 0x0aa7;
if (USBADR3[usb] == 0x00060001 && !NativeUSB(DID)) DID = 0x0aa9;
//NFORCE_USB_END
}
USBID[usb] = DID;
USB20[usb] = (Pci.Hdr.ClassCode[0] == 0x20)?1:0;
USB30[usb] = (Pci.Hdr.ClassCode[0] == 0x30)?1:0;
USB40[usb] = ((Pci.Hdr.ClassCode[0] == 0x20) && USBNForce)?1:0;
usb++;
}
// HDA and HDMI Audio
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_MEDIA) &&
((Pci.Hdr.ClassCode[1] == PCI_CLASS_MEDIA_HDA) ||
(Pci.Hdr.ClassCode[1] == PCI_CLASS_MEDIA_AUDIO))) {
UINT32 codecId = 0, layoutId = 0;
if (!IsHDMIAudio(Handle)) {
// if ((Pci.Hdr.VendorId == 0x8086) &&
// ((Pci.Hdr.DeviceId & 0xFF00) != 0x0C00)) { //0x0C0C is HDMI sound
GetPciADR(DevicePath, &HDAADR1, NULL, NULL);
if (gSettings.HDALayoutId > 0) {
// layoutId is specified - use it
layoutId = (UINT32)gSettings.HDALayoutId;
DBG("Audio HDA (addr:0x%x) setting specified layout-id=%d (0x%x)\n", HDAADR1, layoutId, layoutId);
}
HDAFIX = TRUE;
HDAcodecId = codecId;
HDAlayoutId = layoutId;
} else { //HDMI
GetPciADR(DevicePath, &HDMIADR1, &HDMIADR2, NULL);
GFXHDAFIX = TRUE;
}
}
// LPC
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA)) {
LPCBFIX = get_lpc_model(deviceid);
}
// IDE device
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_IDE)) {
GetPciADR(DevicePath, &IDEADR1, &IDEADR2, NULL);
// DBG("IDEADR1 = 0x%x, IDEADR2 = 0x%x\n", IDEADR1, IDEADR2);
IDEFIX = get_ide_model(deviceid);
IDEVENDOR = Pci.Hdr.VendorId;
}
// SATA
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_SATADPA) &&
(Pci.Hdr.ClassCode[0] == 0x00)) {
GetPciADR(DevicePath, &SATAADR1, &SATAADR2, NULL);
// DBG("SATAADR1 = 0x%x, SATAADR2 = 0x%x\n", SATAADR1, SATAADR2);
SATAFIX = get_ide_model(deviceid);
SATAVENDOR = Pci.Hdr.VendorId;
}
// SATA AHCI
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_SATADPA) &&
(Pci.Hdr.ClassCode[0] == 0x01)) {
GetPciADR(DevicePath, &SATAAHCIADR1, &SATAAHCIADR2, NULL);
// DBG("SATAAHCIADR1 = 0x%x, SATAAHCIADR2 = 0x%x\n", SATAAHCIADR1, SATAAHCIADR2);
// AHCIFIX = get_ahci_model(deviceid);
SATAAHCIVENDOR = Pci.Hdr.VendorId;
}
}
// detected finish
}
}
}
}
UINT8 slash[] = {0x5c, 0};
VOID InsertScore(UINT8* dsdt, UINT32 off2, INTN root)
{
UINT8 NumNames = 0;
UINT32 ind = 0, i;
CHAR8 buf[31];
if (dsdt[off2 + root] == 0x2E) {
NumNames = 2;
off2 += (UINT32)(root + 1);
} else if (dsdt[off2 + root] == 0x2F) {
NumNames = dsdt[off2 + root + 1];
off2 += (UINT32)(root + 2);
} else if (dsdt[off2 + root] != 0x00) {
NumNames = 1;
off2 += (UINT32)root;
}
if (NumNames > 4) {
DBG(" strange NumNames=%d\n", NumNames);
NumNames = 1;
}
NumNames *= 4;
CopyMem(buf + ind, dsdt + off2, NumNames);
ind += NumNames;
// apianti - This generates a memcpy call
/*
for (i = 0; i < NumNames; i++) {
buf[ind++] = dsdt[off2 + i];
}
*/
i = 0;
while (i < 127) {
buf[ind++] = acpi_cpu_score[i];
if (acpi_cpu_score[i] == 0) {
break;
}
i++;
}
CopyMem(acpi_cpu_score, buf, ind);
acpi_cpu_score[ind] = 0;
}
VOID findCPU(UINT8* dsdt, UINT32 length)
{
UINT32 i, k, size;
UINT32 SBSIZE = 0, SBADR = 0;
BOOLEAN SBFound = FALSE;
UINT32 off2, j1;
if (acpi_cpu_score) {
FreePool(acpi_cpu_score);
}
acpi_cpu_score = AllocateZeroPool(128);
acpi_cpu_count = 0;
// 5B 83 41 0C 5C 2E 5F 50 52 5F 43 50 55 30 01 10
// 10 00 00 06
//one another kind
/*
5B 82 4D 95 53 43 4B 30 08 5F 48 49 44 0D 41 43
50 49 30 30 30 34 00 08 5F 55 49 44 0D 43 50 55
53 43 4B 30 00 08 53 43 4B 4E 00 08 4C 53 54 41
0A FF 14 28 5F 53 54 41 00 70 0D 43 50 55 53 43
4B 30 00 43 55 55 30 70 50 53 54 41 00 60 7B 60
0A 03 61 70 61 4C 53 54 41 A4 60
5B 83 4A 04 43 30 30 30 00 10 04 00 00 06 08 5F 48 49 44 0D 41
43 50 49 30 30 30 37 00 08 5F 55 49 44 0D 50 43
49 30 2D 43 50 30 30 30 00 08 5F 50 58 4D 00
//
Device (SCK0)
{
Name (_HID, "ACPI0004") // _HID: Hardware ID
Name (_UID, "CPUSCK0") // _UID: Unique ID
Name (SCKN, Zero)
Name (LSTA, 0xFF)
Method (_STA, 0, NotSerialized) // _STA: Status
{
Store ("CPUSCK0", CUU0)
Store (PSTA (Zero), Local0)
And (Local0, 0x03, Local1)
Store (Local1, LSTA)
Return (Local0)
}
Processor (C000, 0x00, 0x00000410, 0x06)
{
Name (_HID, "ACPI0007") // _HID: Hardware ID
Name (_UID, "PCI0-CP000") // _UID: Unique ID
Name (_PXM, Zero) // _PXM: Device Proximity
*/
for (i = 0; i < length - 20; i++) {
if (dsdt[i] == 0x5B && dsdt[i + 1] == 0x83) { // ProcessorOP
UINT32 j;
UINT32 offset = i + 3 + (dsdt[i + 2] >> 6); // name
BOOLEAN add_name = TRUE;
if (acpi_cpu_count == 0) { //only first time in the cycle
CHAR8 c1 = dsdt[offset + 1];
// I want to determine a scope of PR
//1. if name begin with \\ this is with score
//2. else find outer device or scope until \\ is found
//3. add new name everytime is found
// DBG("first CPU found at %x offset %x\n", i, offset);
if (dsdt[offset] == '\\') {
// "\_PR.CPU0"
j = 1;
if (c1 == 0x2E) {
j = 2;
} else if (c1 == 0x2F) {
c1 = dsdt[offset + 2];
j = 2 + (c1 - 2) * 4;
}
CopyMem(acpi_cpu_score, dsdt + offset + j, 4);
// DBG("slash found\n");
} else {
//--------
j = i - 1; //usually adr = &5B - 1 = sizefield - 3
while (j > 0x24) { //find devices that previous to adr
//check device
k = j + 2;
if ((dsdt[j] == 0x5B) && (dsdt[j + 1] == 0x82) &&
!CmpNum(dsdt, j, TRUE)) { //device candidate
// DBG("device candidate at %x\n", j);
size = get_size(dsdt, k);
if (size) {
if (k + size > i + 3) { //Yes - it is outer
off2 = j + 3 + (dsdt[j + 2] >> 6);
if (dsdt[off2] == '\\') {
// "\_SB.SCL0"
InsertScore(dsdt, off2, 1);
// DBG("acpi_cpu_score calculated as %a\n", acpi_cpu_score);
break;
} else {
InsertScore(dsdt, off2, 0);
// DBG("device inserted in acpi_cpu_score %a\n", acpi_cpu_score);
}
} //else not an outer device
} //else wrong size field - not a device
} //else not a device
// check scope
// a problem 45 43 4F 4E 08 10 84 10 05 5F 53 42 5F
SBSIZE = 0;
if ((dsdt[j] == '_' && dsdt[j + 1] == 'S' &&
dsdt[j + 2] == 'B' && dsdt[j + 3] == '_') ||
(dsdt[j] == '_' && dsdt[j + 1] == 'P' &&
dsdt[j + 2] == 'R' && dsdt[j + 3] == '_')) {
// DBG("score candidate at %x\n", j);
for (j1=0; j1 < 10; j1++) {
if (dsdt[j - j1] != 0x10) {
continue;
}
if (!CmpNum(dsdt, j - j1, TRUE)) {
SBADR = j - j1 + 1;
SBSIZE = get_size(dsdt, SBADR);
// DBG("found Scope(\\_SB) address = 0x%08x size = 0x%08x\n", SBADR, SBSIZE);
if ((SBSIZE != 0) && (SBSIZE < length)) { //if zero or too large then search more
//if found
k = SBADR - 6;
if ((SBADR + SBSIZE) > i + 4) { //Yes - it is outer
SBFound = TRUE;
break; //SB found
} //else not an outer scope
}
}
}
} //else not a scope
if (SBFound) {
InsertScore(dsdt, j, 0);
// DBG("score inserted in acpi_cpu_score %a\n", acpi_cpu_score);
break;
}
j = k - 3; //if found then search again from found
} //while j
//--------
}
}
for (j = 0; j < 4; j++) {
CHAR8 c = dsdt[offset + j];
CHAR8 c1 = dsdt[offset + j + 1];
if(c == '\\') {
offset += 5;
if (c1 == 0x2E) {
offset++;
} else if (c1 == 0x2F) {
c1 = dsdt[offset + j + 2];
offset += 2 + (c1 - 2) * 4;
}
c = dsdt[offset + j];
}
if (!(IS_UPPER(c) || IS_DIGIT(c) || c == '_')) {
add_name = FALSE;
DBG("Invalid character found in ProcessorOP 0x%x!\n", c);
break;
}
}
if (add_name) {
acpi_cpu_name[acpi_cpu_count] = AllocateZeroPool(5);
CopyMem(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4);
acpi_cpu_processor_id[acpi_cpu_count] = dsdt[offset + 4];
i = offset + 5;
//if (acpi_cpu_count == 0)
// acpi_cpu_p_blk = dsdt[i] | (dsdt[i+1] << 8);
if (acpi_cpu_count == 0) {
DBG("Found ACPI CPU: %a ", acpi_cpu_name[acpi_cpu_count]);
} else {
DBG("| %a ", acpi_cpu_name[acpi_cpu_count]);
}
if (++acpi_cpu_count == acpi_cpu_max)
break;
}
}
}
DBG(", within the score: %a\n", acpi_cpu_score);
if (!acpi_cpu_count) {
for (i=0; i<15; i++) {
acpi_cpu_name[i] = AllocateZeroPool(5);
AsciiSPrint(acpi_cpu_name[i], 5, "CPU%1x", i);
acpi_cpu_processor_id[i] = i;
}
}
return;
}
// start => move data start address
// offset => data move how many byte
// len => initial length of the buffer
// return final length of the buffer
// we suppose that buffer allocation is more then len+offset
UINT32 move_data(UINT32 start, UINT8* buffer, UINT32 len, INT32 offset)
{
UINT32 i;
if (offset<0) {
for (i=start; i<len+offset; i++) {
buffer[i] = buffer[i-offset];
}
}
else if (offset>0 && len >=1) { // data move to back
for (i=len-1; i>=start; i--) {
buffer[i+offset] = buffer[i];
}
}
return len + offset;
}
UINT32 get_size(UINT8* Buffer, UINT32 adr)
{
UINT32 temp;
temp = Buffer[adr] & 0xF0; //keep bits 0x30 to check if this is valid size field
if(temp <= 0x30) { // 0
temp = Buffer[adr];
}
else if(temp == 0x40) { // 4
temp = (Buffer[adr] - 0x40) << 0|
Buffer[adr+1] << 4;
}
else if(temp == 0x80) { // 8
temp = (Buffer[adr] - 0x80) << 0|
Buffer[adr+1] << 4|
Buffer[adr+2] << 12;
}
else if(temp == 0xC0) { // C
temp = (Buffer[adr] - 0xC0) << 0|
Buffer[adr+1] << 4|
Buffer[adr+2] << 12|
Buffer[adr+3] << 20;
}
else {
// DBG("wrong pointer to size field at %x\n", adr);
return 0;
}
return temp;
}
//return 1 if new size is two bytes else 0
UINT32 write_offset(UINT32 adr, UINT8* buffer, UINT32 len, INT32 offset)
{
UINT32 i, shift = 0;
UINT32 size = offset + 1;
if (size >= 0x3F) {
for (i=len; i>adr; i--) {
buffer[i+1] = buffer[i];
}
shift = 1;
size += 1;
}
aml_write_size(size, (CHAR8 *)buffer, adr);
return shift;
}
/*
adr - a place to write new size. Size of some object.
buffer - the binary aml codes array
len - its length
sizeoffset - how much the object increased in size
return address shift from original +/- n from outers
When we increase the object size there is a chance that new size field +1
so out devices should also be corrected +1 and this may lead to new shift
*/
//Slice - I excluded check (oldsize <= 0x0fffff && size > 0x0fffff)
//because I think size of DSDT will never be 1Mb
INT32 write_size(UINT32 adr, UINT8* buffer, UINT32 len, INT32 sizeoffset)
{
UINT32 size, oldsize;
INT32 offset = 0;
oldsize = get_size(buffer, adr);
if (!oldsize) {
return 0; //wrong address, will not write here
}
size = oldsize + sizeoffset;
// data move to back
if (oldsize <= 0x3f && size > 0x0fff) {
offset = 2;
} else if ((oldsize <= 0x3f && size > 0x3f) || (oldsize<=0x0fff && size > 0x0fff)) {
offset = 1;
} // data move to front
else if ((size <= 0x3f && oldsize > 0x3f) || (size<=0x0fff && oldsize > 0x0fff)) {
offset = -1;
} else if (oldsize > 0x0fff && size <= 0x3f) {
offset = -2;
}
len = move_data(adr, buffer, len, offset);
size += offset;
aml_write_size(size, (CHAR8 *)buffer, adr); //reuse existing codes
return offset;
}
INT32 FindName(UINT8 *dsdt, INT32 len, CHAR8* name)
{
INT32 i;
for (i = 0; len >= 5 && i < len-5; i++) {
if ((dsdt[i] == 0x08) && (dsdt[i+1] == name[0]) &&
(dsdt[i+2] == name[1]) && (dsdt[i+3] == name[2]) &&
(dsdt[i+4] == name[3])) {
return i+1;
}
}
return 0;
}
BOOLEAN GetName(UINT8 *dsdt, INT32 adr, OUT CHAR8* name, OUT INTN *shift)
{
INT32 i;
INT32 j = (dsdt[adr] == 0x5C)?1:0; //now we accept \NAME
if (!name) {
return FALSE;
}
for (i = adr + j; i < adr + j + 4; i++) {
if ((dsdt[i] < 0x2F) ||
((dsdt[i] > 0x39) && (dsdt[i] < 0x41)) ||
((dsdt[i] > 0x5A) && (dsdt[i] != 0x5F))) {
return FALSE;
}
name[i - adr - j] = dsdt[i];
}
name[4] = 0;
if (shift) {
*shift = j;
}
return TRUE;
}
// if (CmpAdr(dsdt, j, NetworkADR1))
// Name (_ADR, 0x90000)
BOOLEAN CmpAdr (UINT8 *dsdt, UINT32 j, UINT32 PciAdr)
{
// Name (_ADR, 0x001f0001)
return (BOOLEAN)
((dsdt[j + 4] == 0x08) &&
(dsdt[j + 5] == 0x5F) &&
(dsdt[j + 6] == 0x41) &&
(dsdt[j + 7] == 0x44) &&
(dsdt[j + 8] == 0x52) &&
(//--------------------
((dsdt[j + 9] == 0x0C) &&
(dsdt[j + 10] == ((PciAdr & 0x000000ff) >> 0)) &&
(dsdt[j + 11] == ((PciAdr & 0x0000ff00) >> 8)) &&
(dsdt[j + 12] == ((PciAdr & 0x00ff0000) >> 16)) &&
(dsdt[j + 13] == ((PciAdr & 0xff000000) >> 24))
) ||
//--------------------
((dsdt[j + 9] == 0x0B) &&
(dsdt[j + 10] == ((PciAdr & 0x000000ff) >> 0)) &&
(dsdt[j + 11] == ((PciAdr & 0x0000ff00) >> 8)) &&
(PciAdr < 0x10000)
) ||
//-----------------------
((dsdt[j + 9] == 0x0A) &&
(dsdt[j + 10] == (PciAdr & 0x000000ff)) &&
(PciAdr < 0x100)
) ||
//-----------------
((dsdt[j + 9] == 0x00) && (PciAdr == 0)) ||
//------------------
((dsdt[j + 9] == 0x01) && (PciAdr == 1))
)
);
}
BOOLEAN CmpPNP (UINT8 *dsdt, UINT32 j, UINT16 PNP)
{
// Name (_HID, EisaId ("PNP0C0F")) for PNP=0x0C0F BigEndian
if (PNP == 0) {
return (BOOLEAN)
((dsdt[j + 0] == 0x08) &&
(dsdt[j + 1] == 0x5F) &&
(dsdt[j + 2] == 0x48) &&
(dsdt[j + 3] == 0x49) &&
(dsdt[j + 4] == 0x44) &&
(dsdt[j + 5] == 0x0B) &&
(dsdt[j + 6] == 0x41) &&
(dsdt[j + 7] == 0xD0));
}
return (BOOLEAN)
((dsdt[j + 0] == 0x08) &&
(dsdt[j + 1] == 0x5F) &&
(dsdt[j + 2] == 0x48) &&
(dsdt[j + 3] == 0x49) &&
(dsdt[j + 4] == 0x44) &&
(dsdt[j + 5] == 0x0C) &&
(dsdt[j + 6] == 0x41) &&
(dsdt[j + 7] == 0xD0) &&
(dsdt[j + 8] == ((PNP & 0xff00) >> 8)) &&
(dsdt[j + 9] == ((PNP & 0x00ff) >> 0)));
}
INT32 CmpDev(UINT8 *dsdt, UINT32 i, UINT8 *Name)
{
if ((dsdt[i+0] == Name[0]) && (dsdt[i+1] == Name[1]) &&
(dsdt[i+2] == Name[2]) && (dsdt[i+3] == Name[3]) &&
(((dsdt[i-2] == 0x82) && (dsdt[i-3] == 0x5B) && (dsdt[i-1] < 0x40)) ||
((dsdt[i-3] == 0x82) && (dsdt[i-4] == 0x5B) && ((dsdt[i-2] & 0xF0) == 0x40)) ||
((dsdt[i-4] == 0x82) && (dsdt[i-5] == 0x5B) && ((dsdt[i-3] & 0xF0) == 0x80)))
) {
if (dsdt[i-5] == 0x5B) {
return i - 3;
} else if (dsdt[i-4] == 0x5B){
return i - 2;
} else {
return i - 1;
}
}
return 0;
}
//the procedure can find BIN array UNSIGNED CHAR8 sizeof N inside part of large array "dsdt" size of len
// return position or -1 if not found
INT32 FindBin (UINT8 *dsdt, UINT32 len, UINT8* bin, UINT32 N)
{
UINT32 i, j;
BOOLEAN eq;
for (i=0; len >= N && i < len - N; i++) {
eq = TRUE;
for (j=0; j<N; j++) {
if (dsdt[i+j] != bin[j]) {
eq = FALSE;
break;
}
}
if (eq) {
return (INT32)i;
}
}
return -1;
}
//if (!FindMethod(dsdt, len, "DTGP"))
// return address of size field. Assume size not more then 0x0FFF = 4095 bytes
//assuming only short methods
UINT32 FindMethod (UINT8 *dsdt, UINT32 len, /* CONST*/ CHAR8* Name)
{
UINT32 i;
for (i = 0; len >= 7 && i < len - 7; i++) {
if (((dsdt[i] == 0x14) || (dsdt[i+1] == 0x14) || (i>0 && dsdt[i-1] == 0x14)) &&
(dsdt[i+3] == Name[0]) && (dsdt[i+4] == Name[1]) &&
(dsdt[i+5] == Name[2]) && (dsdt[i+6] == Name[3])
){
if (i>0 && dsdt[i-1] == 0x14) return i;
return (dsdt[i+1] == 0x14)?(i+2):(i+1); //pointer to size field
}
}
return 0;
}
//this procedure corrects size of outer method. Embedded methods is not proposed
// adr - a place of changes
// shift - a size of changes
UINT32 CorrectOuterMethod (UINT8 *dsdt, UINT32 len, UINT32 adr, INT32 shift)
{
INT32 i, k;
UINT32 size = 0;
INT32 offset = 0;
// INTN NameShift;
CHAR8 Name[5];
if (shift == 0) {
return len;
}
i = adr; //usually adr = @5B - 1 = sizefield - 3
while (i-- > 0x20) { //find method that previous to adr
k = i + 1;
if ((dsdt[i] == 0x14) && !CmpNum(dsdt, i, FALSE)) { //method candidate
size = get_size(dsdt, k);
if (!size) {
continue;
}
if (((size <= 0x3F) && !GetName(dsdt, k+1, &Name[0], NULL)) ||
((size > 0x3F) && (size <= 0xFFF) && !GetName(dsdt, k+2, &Name[0], NULL)) ||
((size > 0xFFF) && !GetName(dsdt, k+3, &Name[0], NULL))) {
DBG("method found, size=0x%x but name is not\n", size);
continue;
}
if ((k+size) > adr+4) { //Yes - it is outer
DBG("found outer method %a begin=%x end=%x\n", Name, k, k+size);
offset = write_size(k, dsdt, len, shift); //size corrected to sizeoffset at address j
// shift += offset;
len += offset;
} //else not an outer method
break;
}
}
return len;
}
//return final length of dsdt
UINT32 CorrectOuters (UINT8 *dsdt, UINT32 len, UINT32 adr, INT32 shift)
{
INT32 i, j, k;
UINT32 size = 0;
INT32 offset = 0;
UINT32 SBSIZE = 0, SBADR = 0;
BOOLEAN SBFound = FALSE;
if (shift == 0) {
return len;
}
i = adr; //usually adr = @5B - 1 = sizefield - 3
while (i > 0x20) { //find devices that previous to adr
//check device
k = i + 2;
if ((dsdt[i] == 0x5B) && (dsdt[i+1] == 0x82) && !CmpNum(dsdt, i, TRUE)) { //device candidate
size = get_size(dsdt, k);
if (size) {
if ((k+size) > adr+4) { //Yes - it is outer
// DBG("found outer device begin=%x end=%x\n", k, k+size);
offset = write_size(k, dsdt, len, shift); //size corrected to sizeoffset at address j
shift += offset;
len += offset;
} //else not an outer device
} //else wrong size field - not a device
} //else not a device
// check scope
// a problem 45 43 4F 4E 08 10 84 10 05 5F 53 42 5F
SBSIZE = 0;
if (dsdt[i] == '_' && dsdt[i+1] == 'S' && dsdt[i+2] == 'B' && dsdt[i+3] == '_') {
for (j=0; j<10; j++) {
if (dsdt[i-j] != 0x10) {
continue;
}
if (!CmpNum(dsdt, i-j, TRUE)) {
SBADR = i-j+1;
SBSIZE = get_size(dsdt, SBADR);
// DBG("found Scope(\\_SB) address = 0x%08x size = 0x%08x\n", SBADR, SBSIZE);
if ((SBSIZE != 0) && (SBSIZE < len)) { //if zero or too large then search more
//if found
k = SBADR - 6;
if ((SBADR + SBSIZE) > adr+4) { //Yes - it is outer
// DBG("found outer scope begin=%x end=%x\n", SBADR, SBADR+SBSIZE);
offset = write_size(SBADR, dsdt, len, shift);
shift += offset;
len += offset;
SBFound = TRUE;
break; //SB found
} //else not an outer scope
}
}
}
} //else not a scope
if (SBFound) {
break;
}
i = k - 3; //if found then search again from found
}
return len;
}
//ReplaceName(dsdt, len, "AZAL", "HDEF");
INTN ReplaceName(UINT8 *dsdt, UINT32 len, /* CONST*/ CHAR8 *OldName, /* CONST*/ CHAR8 *NewName)
{
UINTN i;
INTN j = 0;
for (i = 0; len >= 4 && i < len - 4; i++) {
if ((dsdt[i+0] == NewName[0]) && (dsdt[i+1] == NewName[1]) &&
(dsdt[i+2] == NewName[2]) && (dsdt[i+3] == NewName[3])) {
if (OldName) {
MsgLog("NewName %a already present, renaming impossible\n", NewName);
} else {
DBG("name %a present at %x\n", NewName, i);
}
return -1;
}
}
if (!OldName) {
return 0;
}
for (i = 0; len >= 4 && i < len - 4; i++) {
if ((dsdt[i+0] == OldName[0]) && (dsdt[i+1] == OldName[1]) &&
(dsdt[i+2] == OldName[2]) && (dsdt[i+3] == OldName[3])) {
MsgLog("Name %a present at 0x%x, renaming to %a\n", OldName, i, NewName);
dsdt[i+0] = NewName[0];
dsdt[i+1] = NewName[1];
dsdt[i+2] = NewName[2];
dsdt[i+3] = NewName[3];
j++;
}
}
return j; //number of replacement
}
//the procedure search nearest "Device" code before given address
//should restrict the search by 6 bytes... OK, 10, .. until dsdt begin
//hmmm? will check device name
UINT32 devFind(UINT8 *dsdt, UINT32 address)
{
UINT32 k = address;
INT32 size = 0;
while (k > 30) {
k--;
if (dsdt[k] == 0x82 && dsdt[k-1] == 0x5B) {
size = get_size(dsdt, k+1);
if (!size) {
continue;
}
if ((k + size + 1) > address) {
return (k+1); //pointer to size
} //else continue
}
}
MsgLog("Device definition before adr=%x not found\n", address);
return 0; //impossible value for fool proof
}
BOOLEAN CustProperties(AML_CHUNK* pack, UINT32 Dev)
{
UINTN i;
BOOLEAN Injected = FALSE;
if (gSettings.NrAddProperties == 0xFFFE) {
return FALSE; // not do this for Arbitrary properties?
}
for (i = 0; i < gSettings.NrAddProperties; i++) {
if (gSettings.AddProperties[i].Device != Dev) {
continue;
}
Injected = TRUE;
if (!gSettings.AddProperties[i].MenuItem.BValue) {
//DBG(" disabled property Key: %a, len: %d\n", gSettings.AddProperties[i].Key, gSettings.AddProperties[i].ValueLen);
} else {
aml_add_string(pack, gSettings.AddProperties[i].Key);
aml_add_byte_buffer(pack, gSettings.AddProperties[i].Value,
(UINT32)gSettings.AddProperties[i].ValueLen);
//DBG(" added property Key: %a, len: %d\n", gSettings.AddProperties[i].Key, gSettings.AddProperties[i].ValueLen);
}
}
return Injected;
}
//len = DeleteDevice("AZAL", dsdt, len);
UINT32 DeleteDevice(/*CONST*/ CHAR8 *Name, UINT8 *dsdt, UINT32 len)
{
UINT32 i, j;
INT32 size = 0, sizeoffset;
MsgLog(" deleting device %a\n", Name);
for (i=20; i<len; i++) {
j = CmpDev(dsdt, i, (UINT8*)Name);
if (j != 0) {
size = get_size(dsdt, j);
if (!size) {
continue;
}
sizeoffset = - 2 - size;
len = move_data(j-2, dsdt, len, sizeoffset);
//to correct outers we have to calculate offset
len = CorrectOuters(dsdt, len, j-3, sizeoffset);
break;
}
}
return len;
}
UINT32 GetPciDevice(UINT8 *dsdt, UINT32 len)
{
UINT32 i;
UINT32 PCIADR = 0, PCISIZE = 0;
for (i=20; i<len; i++) {
// Find Device PCI0 // PNP0A03
if (CmpPNP(dsdt, i, 0x0A03)) {
PCIADR = devFind(dsdt, i);
if (!PCIADR) {
continue;
}
PCISIZE = get_size(dsdt, PCIADR);
if (PCISIZE) {
break;
}
} // End find
}
if (!PCISIZE) {
for (i=20; i<len; i++) {
// Find Device PCIE // PNP0A08
if (CmpPNP(dsdt, i, 0x0A08)) {
PCIADR = devFind(dsdt, i);
if (!PCIADR) {
continue;
}
PCISIZE = get_size(dsdt, PCIADR);
if (PCISIZE) {
break;
}
} // End find
}
}
if (PCISIZE)
return PCIADR;
return 0;
}
// Find PCIRootUID and all need Fix Device
VOID findPciRoot (UINT8 *dsdt, UINT32 len)
{
UINTN j;
UINT32 PCIADR, PCISIZE = 0;
//initialising
NetworkName = FALSE;
DisplayName1 = FALSE;
DisplayName2 = FALSE;
FirewireName = FALSE;
ArptName = FALSE;
XhciName = FALSE;
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
//sample
/*
5B 82 8A F1 05 50 43 49 30 Device (PCI0) {
08 5F 48 49 44 0C 41 D0 0A 08 Name (_HID, EisaId ("PNP0A08"))
08 5F 43 49 44 0C 41 D0 0A 03 Name (_CID, EisaId ("PNP0A03"))
08 5F 41 44 52 00 Name (_ADR, Zero)
14 09 5E 42 4E 30 30 00 A4 00 Method (^BN00, 0, NotSerialized) {Return (Zero)}
14 0B 5F 42 42 4E 00 A4 42 4E 30 30 Method (_BBN, 0, NotSerialized) {Return (BN00 ())}
08 5F 55 49 44 00 Name (_UID, Zero)
14 16 5F 50 52 54 00 Method (_PRT, 0, NotSerialized)
*/
if (PCISIZE > 0) {
// find PCIRootUID
for (j=PCIADR; j<PCIADR+64; j++) {
if (dsdt[j] == '_' && dsdt[j+1] == 'U' && dsdt[j+2] == 'I' && dsdt[j+3] == 'D') {
// Slice - I want to set root to zero instead of keeping original value
if (dsdt[j+4] == 0x0A)
dsdt[j+5] = 0; //AML_BYTE_PREFIX followed by a number
else
dsdt[j+4] = 0; //any other will be considered as ONE or WRONG, replace to ZERO
break;
}
}
} else {
MsgLog("Warning! PCI root is not found!");
}
}
// read device name, replace to ADP1
//check for
/* Name (_PRW, Package (0x02)
{
0x1C,
0x03
}) */
//if absent - add it
/*
5B 82 4B 04 41 44 50 31 //device (ADP1)
08 5F 48 49 44 0D // name (_HID.
41 43 50 49 30 30 30 33 00 // ACPI0003
08 5F 50 52 57 12 06 02 0A 1C 0A 03 //.._PRW..
*/
UINT32 FixADP1 (UINT8* dsdt, UINT32 len)
{
UINT32 i, j;
UINT32 adr, size;
INT32 sizeoffset, shift;
CHAR8 Name[4];
DBG("Start ADP1 fix\n");
shift = FindBin(dsdt, len, (UINT8*)acpi3, sizeof(acpi3));
if (shift < 0) {
// not found - create new one or do nothing
MsgLog("no device(AC) exists\n");
return len;
}
adr = devFind(dsdt, (UINT32)shift);
if (!adr) {
return len;
}
size = get_size(dsdt, adr);
//check name and replace
if (size < 0x40) {
j = adr + 1;
} else {
j = adr + 2;
}
for (i=0; i<4; i++) {
Name[i] = dsdt[j+i];
}
ReplaceName(dsdt, len, Name, "ADP1");
//find PRW
if(FindBin(dsdt+adr, size, (UINT8*)prw1c, 8) >= 0){
DBG("_prw is present\n");
return len;
}
j = adr + size;
sizeoffset = sizeof(prw1c);
len = move_data(j, dsdt, len, sizeoffset);
CopyMem(dsdt + j, prw1c, sizeoffset);
shift = write_size(adr, dsdt, len, sizeoffset);
sizeoffset += shift;
len += shift;
len = CorrectOuters(dsdt, len, adr - 3, sizeoffset);
return len;
}
UINT32 FixAny (UINT8* dsdt, UINT32 len, UINT8* ToFind, UINT32 LenTF, UINT8* ToReplace, UINT32 LenTR)
{
INT32 sizeoffset, adr;
UINT32 i;
BOOLEAN found = FALSE;
if (!ToFind || !LenTF || !LenTR) {
DBG(" invalid patches!\n");
return len;
}
MsgLog(" pattern %02x%02x%02x%02x,", ToFind[0], ToFind[1], ToFind[2], ToFind[3]);
if ((LenTF + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) > len) {
MsgLog(" the patch is too large!\n");
return len;
}
sizeoffset = LenTR - LenTF;
for (i = 20; i < len; ) {
adr = FindBin(dsdt + i, len - i, ToFind, LenTF);
if (adr < 0) {
if (found) {
MsgLog(" ]\n");
} else {
MsgLog(" bin not found / already patched!\n");
}
return len;
}
if (!found) {
MsgLog(" patched at: [");
}
MsgLog(" (%x)", adr);
found = TRUE;
len = move_data(adr + i, dsdt, len, sizeoffset);
if ((LenTR > 0) && (ToReplace != NULL)) {
CopyMem(dsdt + adr + i, ToReplace, LenTR);
}
len = CorrectOuterMethod(dsdt, len, adr + i - 2, sizeoffset);
len = CorrectOuters(dsdt, len, adr + i - 3, sizeoffset);
i += adr + LenTR;
}
MsgLog(" ]\n"); //should not be here
return len;
}
//new method. by goodwin_c
UINT32 FixRenameByBridge2 (UINT8* dsdt, UINT32 len, CHAR8* TgtBrgName, UINT8* ToFind, UINT32 LenTF, UINT8* ToReplace, UINT32 LenTR)
{
INT32 adr;
BOOLEAN found = FALSE;
UINT32 i, k;
UINT32 BrdADR = 0, BridgeSize;
UINT32 PCIADR, PCISIZE = 0;
if (!ToFind || !LenTF || !LenTR) {
DBG(" invalid patches!\n");
return len;
}
if (LenTF != LenTR) {
DBG(" find/replace different size!\n");
return len;
}
DBG(" pattern %02x%02x%02x%02x,", ToFind[0], ToFind[1], ToFind[2], ToFind[3]);
if ((LenTF + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) > len) {
DBG(" the patch is too large!\n");
return len;
}
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) return len; //what is the bad DSDT ?!
DBG("Start ByBridge Rename Fix\n");
for (i=0x20; len >= 10 && i < len - 10; i++) {
if (CmpDev(dsdt, i, (UINT8*)TgtBrgName)) {
BrdADR = devFind(dsdt, i);
if (!BrdADR) {
continue;
}
BridgeSize = get_size(dsdt, BrdADR);
if(!BridgeSize) continue;
if(BridgeSize <= LenTF) continue;
k = 0;
found = FALSE;
while (k <= 100) {
adr = FindBin(dsdt + BrdADR, BridgeSize, ToFind, LenTF);
if (adr < 0) {
if (found) {
DBG(" ]\n");
} else {
DBG(" bin not found / already patched!\n");
}
return len;
}
if (!found) {
DBG(" patched at: [");
}
DBG(" (%x)", adr);
found = TRUE;
if ((LenTR > 0) && (ToReplace != NULL)) {
CopyMem(dsdt + BrdADR + adr, ToReplace, LenTR);
}
k++;
}
}
}
DBG(" ]\n");
return len;
}
UINT32 FIXDarwin (UINT8* dsdt, UINT32 len)
{
CONST UINT32 adr = 0x24;
DBG("Start Darwin Fix\n");
ReplaceName(dsdt, len, "_OSI", "OOSI");
if (gSettings.FixDsdt & FIX_DARWIN) {
darwin[42] = '9'; //windows 2009
}
len = move_data(adr, dsdt, len, sizeof(darwin));
CopyMem(dsdt+adr, darwin, sizeof(darwin));
return len;
}
VOID FixS3D (UINT8* dsdt, UINT32 len)
{
UINT32 i;
DBG("Start _S3D Fix\n");
for (i=20; len >= 5 && i < len - 5; i++) {
if ((dsdt[i + 0] == 0x08) &&
(dsdt[i + 1] == '_') &&
(dsdt[i + 2] == 'S') &&
(dsdt[i + 3] == '3') &&
(dsdt[i + 4] == 'D') &&
(dsdt[i + 5] == 0x0A) &&
(dsdt[i + 6] == 0x02)) {
dsdt[i + 6] = 3;
}
}
}
UINT32 AddPNLF (UINT8 *dsdt, UINT32 len)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer = NULL;
EFI_HANDLE Handle;
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
UINTN HandleCount = 0;
UINTN HandleIndex;
UINTN Segment;
UINTN Bus;
UINTN Device;
UINTN Function;
UINT32 i; //, j, size;
UINT32 adr = 0;
DBG("Start PNLF Fix\n");
if (FindBin(dsdt, len, (UINT8*)app2, 10) >= 0) {
return len; //the device already exists
}
//search PWRB PNP0C0C
for (i=0x20; len >= 6 && i < len - 6; i++) {
if (CmpPNP(dsdt, i, 0x0C0C)) {
DBG("found PWRB at %x\n", i);
adr = devFind(dsdt, i);
break;
}
}
if (!adr) {
//search battery
DBG("not found PWRB, look BAT0\n");
for (i=0x20; len >= 6 && i < len - 6; i++) {
if (CmpPNP(dsdt, i, 0x0C0A)) {
adr = devFind(dsdt, i);
DBG("found BAT0 at %x\n", i);
break;
}
}
}
if (!adr) {
return len;
}
// _UID reworked by Sherlocks. 2018.10.08
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiPciIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (!EFI_ERROR (Status)) {
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
Handle = HandleBuffer[HandleIndex];
Status = gBS->HandleProtocol (
Handle,
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo
);
if (!EFI_ERROR (Status)) {
PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint32,
0,
sizeof (Pci) / sizeof (UINT32),
&Pci
);
}
if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_DISPLAY) &&
((Pci.Hdr.ClassCode[1] == PCI_CLASS_DISPLAY_VGA) ||
(Pci.Hdr.ClassCode[1] == PCI_CLASS_DISPLAY_OTHER))) {
switch (Pci.Hdr.VendorId) {
case 0x8086:
// followed standard _UID of AppleBacklight
// it works for both default and AppleBacklightInjector
switch (Pci.Hdr.DeviceId) {
case 0x2772: // "Intel GMA 950"
case 0x2776: // "Intel GMA 950"
case 0x27A2: // "Intel GMA 950"
case 0x27A6: // "Intel GMA 950"
case 0x27AE: // "Intel GMA 950"
case 0xA001: // "Intel GMA 3150"
case 0xA002: // "Intel GMA 3150"
case 0xA011: // "Intel GMA 3150"
case 0xA012: // "Intel GMA 3150"
case 0x2A02: // "Intel GMA X3100"
case 0x2A03: // "Intel GMA X3100"
case 0x2A12: // "Intel GMA X3100"
case 0x2A13: // "Intel GMA X3100"
case 0x0042: // "Intel HD Graphics"
case 0x0046: // "Intel HD Graphics"
// _UID: 10
break;
case 0x0102: // "Intel HD Graphics 2000"
case 0x0106: // "Intel HD Graphics 2000"
case 0x010A: // "Intel HD Graphics P3000"
case 0x0112: // "Intel HD Graphics 3000"
case 0x0116: // "Intel HD Graphics 3000"
case 0x0122: // "Intel HD Graphics 3000"
case 0x0126: // "Intel HD Graphics 3000"
case 0x0152: // "Intel HD Graphics 2500"
case 0x0156: // "Intel HD Graphics 2500"
case 0x015A: // "Intel HD Graphics 2500"
case 0x0162: // "Intel HD Graphics 4000"
case 0x0166: // "Intel HD Graphics 4000"
case 0x016A: // "Intel HD Graphics P4000"
((CHAR8*)pnlf)[39] = 0x0E; // _UID: 14
break;
case 0x0412: // "Intel HD Graphics 4600"
case 0x0416: // "Intel HD Graphics 4600"
case 0x041A: // "Intel HD Graphics P4600"
case 0x041E: // "Intel HD Graphics 4400"
case 0x0422: // "Intel HD Graphics 5000"
case 0x0426: // "Intel HD Graphics 5000"
case 0x042A: // "Intel HD Graphics 5000"
case 0x0A06: // "Intel HD Graphics"
case 0x0A16: // "Intel HD Graphics 4400"
case 0x0A1E: // "Intel HD Graphics 4200"
case 0x0A22: // "Intel Iris Graphics 5100"
case 0x0A26: // "Intel HD Graphics 5000"
case 0x0A2A: // "Intel Iris Graphics 5100"
case 0x0A2B: // "Intel Iris Graphics 5100"
case 0x0A2E: // "Intel Iris Graphics 5100"
case 0x0D12: // "Intel HD Graphics 4600"
case 0x0D16: // "Intel HD Graphics 4600"
case 0x0D22: // "Intel Iris Pro Graphics 5200"
case 0x0D26: // "Intel Iris Pro Graphics 5200"
case 0x0D2A: // "Intel Iris Pro Graphics 5200"
case 0x0D2B: // "Intel Iris Pro Graphics 5200"
case 0x0D2E: // "Intel Iris Pro Graphics 5200"
case 0x1612: // "Intel HD Graphics 5600"
case 0x1616: // "Intel HD Graphics 5500"
case 0x161E: // "Intel HD Graphics 5300"
case 0x1626: // "Intel HD Graphics 6000"
case 0x162B: // "Intel Iris Graphics 6100"
case 0x162D: // "Intel Iris Pro Graphics P6300"
case 0x1622: // "Intel Iris Pro Graphics 6200"
case 0x162A: // "Intel Iris Pro Graphics P6300"
((CHAR8*)pnlf)[39] = 0x0F; // _UID: 15
break;
default:
((CHAR8*)pnlf)[39] = 0x10; // _UID: 16
break;
}
break;
default:
// ATI/NVIDIA
// _UID: 10
break;
}
}
}
}
i = adr - 2;
len = move_data(i, dsdt, len, sizeof(pnlf));
CopyMem(dsdt+i, pnlf, sizeof(pnlf));
len = CorrectOuters(dsdt, len, adr-3, sizeof(pnlf));
return len;
}
UINT32 FixRTC (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j, k, l;
UINT32 IOADR = 0;
UINT32 RESADR = 0;
UINT32 adr = 0;
UINT32 rtcsize = 0;
INT32 shift, sizeoffset = 0;
DBG("Start RTC Fix\n");
for (j=20; j<len; j++) {
// Find Device RTC // Name (_HID, EisaId ("PNP0B00")) for RTC
if (CmpPNP(dsdt, j, 0x0B00))
{
adr = devFind(dsdt, j);
if (!adr) {
continue;
}
rtcsize = get_size(dsdt, adr);
if (rtcsize) {
break;
}
} // End RTC
}
if (!rtcsize) {
DBG("BUG! rtcsize not found\n");
return len;
}
for (i=adr+4; i<adr+rtcsize; i++) {
// IO (Decode16, ((0x0070, 0x0070)) =>> find this
if (dsdt[i] == 0x70 && dsdt[i+1] == 0x00 && dsdt[i+2] == 0x70 && dsdt[i+3] == 0x00) {
if (dsdt[i+5] == 0x08 && gSettings.Rtc8Allowed) {
MsgLog("CMOS reset not will be, patch length is not needed\n");
} else {
// First Fix RTC CMOS Reset Problem
if (dsdt[i+4] != 0x00 || dsdt[i+5] != 0x02) { //dsdt[j+4] => Alignment dsdt[j+5] => Length
dsdt[i+4] = 0x00; //Alignment
dsdt[i+5] = 0x02; //Length
MsgLog("found RTC Length not match, Maybe will cause CMOS reset, will patch it.\n");
}
}
for (l = adr + 4; l < i; l++) {
if (dsdt[l] == 0x11 && dsdt[l+2] == 0x0A) {
RESADR = l + 1; //Format 11, size, 0A, size-3,... 79, 00
IOADR = l + 3; //IO (Decode16 ==> 47, 01
}
}
break;
}
if ((dsdt[i+1] == 0x5B) && (dsdt[i+2] == 0x82)) {
break; //end of RTC device and begin of new Device()
}
}
for (l = adr + 4; l < adr + rtcsize; l++) {
if ((dsdt[l] == 0x22) && (l>IOADR) && (l<IOADR+dsdt[IOADR])) { // Had IRQNoFlag
for (k=l; k<l+20; k++) {
if ((dsdt[k] == 0x79) || ((dsdt[k] == 0x47) && (dsdt[k+1] == 0x01)) ||
((dsdt[k] == 0x86) && (dsdt[k+1] == 0x09))) {
sizeoffset = l - k; //usually = -3
MsgLog("found RTC had IRQNoFlag will move %d bytes\n", sizeoffset);
// First move offset byte remove IRQNoFlag
len = move_data(l, dsdt, len, sizeoffset);
DBG("...len=%x\n", len);
// Fix IO (Decode16, size and _CRS size
dsdt[RESADR] += (UINT8)sizeoffset;
dsdt[IOADR] += (UINT8)sizeoffset;
break;
}
}
}
// if offset > 0 Fix Device RTC size
if (sizeoffset != 0) {
// RTC size
shift = write_size(adr, dsdt, len, sizeoffset);
sizeoffset += shift; //sizeoffset changed
len += shift;
DBG("new size written to %x shift=%x len=%x\n", adr, shift, len);
len = CorrectOuters(dsdt, len, adr-3, sizeoffset);
DBG("len after correct outers %x\n", len);
sizeoffset = 0;
} // sizeoffset if
} // l loop
return len;
}
UINT32 FixTMR (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j, k;
UINT32 IOADR = 0;
UINT32 RESADR = 0;
UINT32 adr = 0;
UINT32 TMRADR, tmrsize = 0;
INT32 offset = 0, sizeoffset = 0;
DBG("Start TMR Fix\n");
for (j=20; j<len; j++) {
// Find Device TMR PNP0100
if (CmpPNP(dsdt, j, 0x0100)) {
TMRADR = devFind(dsdt, j);
adr = TMRADR;
if (!adr) {
continue;
}
tmrsize = get_size(dsdt, adr);
// DBG("TMR size=%x at %x\n", tmrsize, adr);
if (tmrsize) {
break;
}
} // End TMR
}
if (!adr) {
DBG("TMR device not found!\n");
return len;
}
// Fix TMR
// Find Name(_CRS, ResourceTemplate ()) find ResourceTemplate 0x11
j = 0;
for (i=adr; i<adr+tmrsize; i++) { //until next Device()
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
j = get_size(dsdt, IOADR);
}
if (dsdt[i] == 0x22) { // Had IRQNoFlag
for (k=i; k<i+j; k++) {
if ((dsdt[k] == 0x79) || ((dsdt[k] == 0x47) && (dsdt[k+1] == 0x01)) ||
((dsdt[k] == 0x86) && (dsdt[k+1] == 0x09))) {
sizeoffset = i - k;
//DBG("found TMR 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;
break;
}
}
}
// if offset > 0 Fix Device TMR size
if (sizeoffset != 0)
{
// TMR size
offset = write_size(adr, dsdt, len, sizeoffset);
sizeoffset += offset;
len += offset;
len = CorrectOuters(dsdt, len, adr-3, sizeoffset);
sizeoffset = 0;
} // offset if
if ((dsdt[i+1] == 0x5B) && (dsdt[i+2] == 0x82)) {
break; //end of TMR device and begin of new Device()
}
} // i loop
return len;
}
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;
MsgLog("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;
}
UINT32 FixHPET (UINT8* dsdt, UINT32 len)
{
UINT32 i, j;
UINT32 adr = 0;
UINT32 hpetsize = 0;
INT32 sizeoffset = sizeof(hpet0);
INT32 shift = 0;
UINT32 LPCBADR = 0, LPCBSIZE = 0;
MsgLog("Start HPET Fix\n");
//have to find LPC
for (j=0x20; len >= 10 && j < len - 10; j++) {
if (CmpAdr(dsdt, j, 0x001F0000)) {
LPCBADR = devFind(dsdt, j);
if (!LPCBADR) {
continue;
}
LPCBSIZE = get_size(dsdt, LPCBADR);
} // End LPCB find
}
if (!LPCBSIZE) {
MsgLog("No LPCB device! Patch HPET will not be applied\n");
return len;
}
for (j=20; j<len; j++) {
// Find Device HPET // PNP0103
if (CmpPNP(dsdt, j, 0x0103)) {
adr = devFind(dsdt, j);
if (!adr) {
continue;
}
hpetsize = get_size(dsdt, adr);
if (hpetsize) {
break;
}
} // End HPET
}
if (hpetsize) {
i = adr - 2; //pointer to device HPET
j = hpetsize + 2;
sizeoffset -= j;
len = move_data(i, dsdt, len, sizeoffset);
// add new HPET code
CopyMem(dsdt+i, hpet0, sizeof(hpet0));
len = CorrectOuters(dsdt, len, i - 3, sizeoffset); //assume LPC may be outer or not
} else {
i = LPCBADR + LPCBSIZE; //pointer to the end of LPC
//in this case LPC becomes Outer device
shift = write_size(LPCBADR, dsdt, len, sizeoffset); //correct LPC
sizeoffset += shift;
len += shift;
i += shift;
len = move_data(i, dsdt, len, sizeof(hpet0));
// add new HPET code
CopyMem(dsdt + i, hpet0, sizeof(hpet0));
len = CorrectOuters(dsdt, len, LPCBADR - 3, sizeoffset); //outer for LPC
}
return len;
}
CHAR8 dataLPC[] = {0x18, 0x3A, 0x00, 0x00};
UINT32 FIXLPCB (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j, k;
INT32 sizeoffset, shift = 0, Size;
UINT32 LPCBADR = 0, LPCBSIZE = 0, LPCBADR1 = 0;
AML_CHUNK* root;
AML_CHUNK* met;
AML_CHUNK* pack;
CHAR8 *lpcb;
CHAR8 NameCard[32];
DBG("Start LPCB Fix\n");
//DBG("len = 0x%08x\n", len);
//have to find LPC
for (j=0x20; len >= 10 && j < len - 10; j++) {
if (CmpAdr(dsdt, j, 0x001F0000))
{
LPCBADR = devFind(dsdt, j);
if (!LPCBADR) {
continue;
}
LPCBSIZE = get_size(dsdt, LPCBADR);
device_name[3] = AllocateZeroPool(5);
CopyMem(device_name[3], dsdt + j, 4);
MsgLog("found LPCB device NAME(_ADR,0x001F0000) at %x And Name is %a\n", j,
device_name[3]);
if (LPCBSIZE) break;
} // End LPCB find
}
if (!LPCBSIZE) return len;
LPCBADR1 = LPCBADR + LPCBSIZE;
ReplaceName(dsdt, len, device_name[3], "LPCB");
if (LPCBADR) { // bridge or device
i = LPCBADR;
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_LPC) != 0) {
Size = get_size(dsdt, k);
if(!Size) {
return len;
}
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
//to correct outers we have to calculate offset
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
MsgLog("_DSM in LPC already exists, dropped\n");
} else {
MsgLog("_DSM already exists, patch LPC will not be applied\n");
return len;
}
}
}
root = aml_create_node(NULL);
// add Method(_DSM,4,NotSerialized) for LPC
met = aml_add_method(root, "_DSM", 4);
met = aml_add_store(met);
pack = aml_add_package(met);
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, dataLPC, 4);
AsciiSPrint(NameCard, 32, "pci8086,3a18");
aml_add_string(pack, "name");
aml_add_string_buffer(pack, (CHAR8 *)&NameCard[0]);
aml_add_string(pack, "compatible");
aml_add_string_buffer(pack, (CHAR8 *)&NameCard[0]);
CustProperties(pack, DEV_LPC);
aml_add_local0(met);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root);
lpcb = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, lpcb, 0);
aml_destroy_node(root);
// add LPCB code
len = move_data(LPCBADR1, dsdt, len, sizeoffset);
CopyMem(dsdt + LPCBADR1, lpcb, sizeoffset);
shift = write_size(LPCBADR, dsdt, len, sizeoffset);
sizeoffset += shift;
len += shift;
len = CorrectOuters(dsdt, len, LPCBADR-3, sizeoffset);
FreePool(lpcb);
return len;
}
//CONST
CHAR8 Yes[] = {0x01,0x00,0x00,0x00};
CHAR8 data2[] = {0xe0,0x00,0x56,0x28};
CHAR8 VenATI[] = {0x02, 0x10};
UINT32 FIXDisplay (UINT8 *dsdt, UINT32 len, INT32 VCard)
{
UINT32 i = 0, j, k;
INT32 sizeoffset = 0;
UINT32 PCIADR = 0, PCISIZE = 0, Size;
CHAR8 *display;
UINT32 devadr=0, devsize=0, devadr1=0, devsize1=0;
BOOLEAN DISPLAYFIX = FALSE;
BOOLEAN NonUsable = FALSE;
BOOLEAN DsmFound = FALSE;
BOOLEAN NeedHDMI = !!(gSettings.FixDsdt & FIX_HDMI);
AML_CHUNK *root = NULL;
AML_CHUNK *gfx0, *peg0;
AML_CHUNK *met, *met2;
AML_CHUNK *pack;
UINT32 FakeID = 0;
UINT32 FakeVen = 0;
DisplayName1 = FALSE;
if (!DisplayADR1[VCard]) return len;
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) return len; //what is the bad DSDT ?!
MsgLog("Start Display%d Fix\n", VCard);
root = aml_create_node(NULL);
//search DisplayADR1[0]
for (j=0x20; len >= 10 && j < len - 10; j++) {
if (CmpAdr(dsdt, j, DisplayADR1[VCard])) { //for example 0x00020000=2,0
devadr = devFind(dsdt, j); //PEG0@2,0
if (!devadr) {
continue;
}
devsize = get_size(dsdt, devadr); //sizeof PEG0 0x35
if (devsize) {
DisplayName1 = TRUE;
break;
}
} // End Display1
}
//what if PEG0 is not found?
if (devadr) {
for (j=devadr; j<devadr+devsize; j++) { //search card inside PEG0@0
if (CmpAdr(dsdt, j, DisplayADR2[VCard])) { //else DISPLAYFIX==false
devadr1 = devFind(dsdt, j); //found PEGP
if (!devadr1) {
continue;
}
devsize1 = get_size(dsdt, devadr1);
if (devsize1) {
MsgLog("Found internal video device %x @%x\n", DisplayADR2[VCard], devadr1);
DISPLAYFIX = TRUE;
break;
}
}
}
if (!DISPLAYFIX) {
for (j=devadr; j<devadr+devsize; j++) { //search card inside PEGP@0
if (CmpAdr(dsdt, j, 0xFFFF)) { //Special case? want to change to 0
devadr1 = devFind(dsdt, j); //found PEGP
if (!devadr1) {
continue;
}
devsize1 = get_size(dsdt, devadr1); //13
if (devsize1) {
if (gSettings.ReuseFFFF) {
dsdt[j+10] = 0;
dsdt[j+11] = 0;
MsgLog("Found internal video device FFFF@%x, ReUse as 0\n", devadr1);
} else {
NonUsable = TRUE;
MsgLog("Found internal video device FFFF@%x, unusable\n", devadr1);
}
DISPLAYFIX = TRUE;
break;
}
}
}
}
i = 0;
if (DISPLAYFIX) { // device on bridge found
i = devadr1;
} else if (DisplayADR2[VCard] == 0xFFFE) { //builtin
i = devadr;
DISPLAYFIX = TRUE;
devadr1 = devadr;
MsgLog(" builtin display\n");
}
if (i != 0) {
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((((dropDSM & DEV_ATI) != 0) && (DisplayVendor[VCard] == 0x1002)) ||
(((dropDSM & DEV_NVIDIA)!= 0) && (DisplayVendor[VCard] == 0x10DE)) ||
(((dropDSM & DEV_INTEL) != 0) && (DisplayVendor[VCard] == 0x8086))) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset); //kill _DSM
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
MsgLog("_DSM in display already exists, dropped\n");
} else {
MsgLog("_DSM already exists, patch display will not be applied\n");
// return len;
DisplayADR1[VCard] = 0; //xxx
DsmFound = TRUE;
}
}
}
}
if (!DisplayName1) {
peg0 = aml_add_device(root, "PEG0");
aml_add_name(peg0, "_ADR");
aml_add_dword(peg0, DisplayADR1[VCard]);
MsgLog("add device PEG0\n");
} else
peg0 = root;
if (!DISPLAYFIX) { //bridge or builtin not found
gfx0 = aml_add_device(peg0, "GFX0");
MsgLog("add device GFX0\n");
aml_add_name(gfx0, "_ADR");
if (DisplayADR2[VCard] > 0x3F)
aml_add_dword(gfx0, DisplayADR2[VCard]);
else
aml_add_byte(gfx0, (UINT8)DisplayADR2[VCard]);
} else {
gfx0 = peg0;
}
if (
DsmFound ||
(
!NeedHDMI &&
(
((DisplayVendor[VCard] == 0x8086) && (gSettings.InjectIntel || !gSettings.FakeIntel)) ||
((DisplayVendor[VCard] == 0x10DE) && (gSettings.InjectNVidia || !gSettings.FakeNVidia)) ||
((DisplayVendor[VCard] == 0x1002) && (gSettings.InjectATI || !gSettings.FakeATI))
)
)
) {
MsgLog("Skipping Method(_DSM) for %04x card\n", DisplayVendor[VCard]);
goto Skip_DSM;
}
MsgLog("Creating Method(_DSM) for %04x card\n", DisplayVendor[VCard]);
met = aml_add_method(gfx0, "_DSM", 4);
met2 = aml_add_store(met);
pack = aml_add_package(met2);
if (NeedHDMI) {
aml_add_string(pack, "hda-gfx");
aml_add_string_buffer(pack, (gSettings.UseIntelHDMI && DisplayVendor[VCard] != 0x8086) ? "onboard-2" : "onboard-1");
}
switch (DisplayVendor[VCard]) {
case 0x8086:
if (gSettings.FakeIntel) {
FakeID = gSettings.FakeIntel >> 16;
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeID, 4);
FakeVen = gSettings.FakeIntel & 0xFFFF;
aml_add_string(pack, "vendor-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeVen, 4);
}
break;
case 0x10DE:
if (gSettings.FakeNVidia) {
FakeID = gSettings.FakeNVidia >> 16;
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeID, 4);
FakeVen = gSettings.FakeNVidia & 0xFFFF;
aml_add_string(pack, "vendor-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeVen, 4);
}
break;
case 0x1002:
if (gSettings.FakeATI) {
FakeID = gSettings.FakeATI >> 16;
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeID, 4);
aml_add_string(pack, "ATY,DeviceID");
aml_add_byte_buffer(pack, (CHAR8*)&FakeID, 2);
FakeVen = gSettings.FakeATI & 0xFFFF;
aml_add_string(pack, "vendor-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeVen, 4);
aml_add_string(pack, "ATY,VendorID");
aml_add_byte_buffer(pack, (CHAR8*)&FakeVen, 2);
}/* else {
aml_add_string(pack, "ATY,VendorID");
aml_add_byte_buffer(pack, VenATI, 2);
}*/
break;
}
aml_add_local0(met);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
Skip_DSM:
//add _sun
switch (DisplayVendor[VCard]) {
case 0x10DE:
case 0x1002:
Size = get_size(dsdt, i);
j = (DisplayVendor[VCard] == 0x1002) ? 0 : 1;
k = FindMethod(dsdt + i, Size, "_SUN");
if (k == 0) {
k = FindName(dsdt + i, Size, "_SUN");
if (k == 0) {
aml_add_name(gfx0, "_SUN");
aml_add_dword(gfx0, SlotDevices[j].SlotID);
} else {
//we have name sun, set the number
if (dsdt[k + 4] == 0x0A) {
dsdt[k + 5] = SlotDevices[j].SlotID;
}
}
} else {
MsgLog("Warning: Method(_SUN) found for %04x card\n", DisplayVendor[VCard]);
}
break;
}
if (!NonUsable) {
//now insert video
DBG("now inserting Video device\n");
aml_calculate_size(root);
display = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, display, 0);
aml_destroy_node(root);
if (DisplayName1) { //bridge is present
// move data to back for add Display
DBG("... into existing bridge\n");
if (!DISPLAYFIX || (DisplayADR2[VCard] == 0xFFFE)) { //subdevice absent
devsize = get_size(dsdt, devadr);
if (!devsize) {
DBG("BUG! Address of existing PEG0 is lost %x\n", devadr);
FreePool(display);
return len;
}
i = devadr + devsize;
len = move_data(i, dsdt, len, sizeoffset);
CopyMem(dsdt+i, display, sizeoffset);
j = write_size(devadr, dsdt, len, sizeoffset); //correct bridge size
sizeoffset += j;
len += j;
len = CorrectOuters(dsdt, len, devadr-3, sizeoffset);
} else {
devsize1 = get_size(dsdt, devadr1);
if (!devsize1) {
FreePool(display);
return len;
}
i = devadr1 + devsize1;
len = move_data(i, dsdt, len, sizeoffset);
CopyMem(dsdt+i, display, sizeoffset);
j = write_size(devadr1, dsdt, len, sizeoffset);
sizeoffset += j;
len += j;
len = CorrectOuters(dsdt, len, devadr1-3, sizeoffset);
}
} else { //insert PEG0 into PCI0 at the end
//PCI corrected so search again
DBG("... into created bridge\n");
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) return len; //what is the bad DSDT ?!
i = PCIADR + PCISIZE;
// devadr = i + 2; //skip 5B 82
len = move_data(i, dsdt, len, sizeoffset);
CopyMem(dsdt + i, display, sizeoffset);
// Fix PCI0 size
k = write_size(PCIADR, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
// devadr += k;
k = CorrectOuters(dsdt, len, PCIADR-3, sizeoffset);
// devadr += k - len;
len = k;
}
FreePool(display);
}
return len;
}
UINT32 AddHDMI (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j, k;
INT32 sizeoffset = 0;
UINT32 PCIADR = 0, PCISIZE = 0, Size;
CHAR8 *hdmi = NULL;
UINT32 devadr=0, BridgeSize=0, devadr1=0; //, devsize1=0;
BOOLEAN BridgeFound = FALSE;
BOOLEAN HdauFound = FALSE;
AML_CHUNK* brd = NULL;
AML_CHUNK *root = NULL;
AML_CHUNK *met, *met2;
AML_CHUNK *pack;
if (!HDMIADR1) return len;
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) return len; //what is the bad DSDT ?!
DBG("Start HDMI%d Fix\n");
// Device Address
for (i=0x20; len >= 10 && i < len - 10; i++) {
if (CmpAdr(dsdt, i, HDMIADR1)) {
devadr = devFind(dsdt, i);
if (!devadr) {
continue;
}
BridgeSize = get_size(dsdt, devadr);
if (!BridgeSize) {
continue;
}
BridgeFound = TRUE;
if (HDMIADR2 != 0xFFFE){
for (k = devadr + 9; k < devadr + BridgeSize; k++) {
if (CmpAdr(dsdt, k, HDMIADR2))
{
devadr1 = devFind(dsdt, k);
if (!devadr1) {
continue;
}
device_name[11] = AllocateZeroPool(5);
CopyMem(device_name[11], dsdt+k, 4);
DBG("found HDMI device [0x%08x:%x] at %x and Name is %a\n",
HDMIADR1, HDMIADR2, devadr1, device_name[11]);
ReplaceName(dsdt + devadr, BridgeSize, device_name[11], "HDAU");
HdauFound = TRUE;
break;
}
}
if (!HdauFound) {
DBG("have no HDMI device while HDMIADR2=%x\n", HDMIADR2);
devadr1 = devadr;
}
} else {
devadr1 = devadr;
}
break;
} // End if devadr1 find
}
if (BridgeFound) { // bridge or device
if (HdauFound) {
i = devadr1;
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_HDMI) != 0) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in HDAU already exists, dropped\n");
} else {
DBG("_DSM already exists, patch HDAU will not be applied\n");
return len;
}
}
}
root = aml_create_node(NULL);
//what to do if no HDMI bridge?
} else {
brd = aml_create_node(NULL);
root = aml_add_device(brd, "HDM0");
aml_add_name(root, "_ADR");
aml_add_dword(root, HDMIADR1);
DBG("Created bridge device with ADR=0x%x\n", HDMIADR1);
}
DBG("HDMIADR1=%x HDMIADR2=%x\n", HDMIADR1, HDMIADR2);
if (!HdauFound && (HDMIADR2 != 0xFFFE)) //there is no HDMI device at dsdt, creating new one
{
AML_CHUNK* dev = aml_add_device(root, "HDAU");
aml_add_name(dev, "_ADR");
if (HDMIADR2) {
if (HDMIADR2 > 0x3F)
aml_add_dword(dev, HDMIADR2);
else
aml_add_byte(dev, (UINT8)HDMIADR2);
} else {
aml_add_byte(dev, 0x01);
}
met = aml_add_method(dev, "_DSM", 4);
} else {
//HDAU device already present
met = aml_add_method(root, "_DSM", 4);
}
met2 = aml_add_store(met);
pack = aml_add_package(met2);
if (!gSettings.NoDefaultProperties) {
aml_add_string(pack, "hda-gfx");
if (gSettings.UseIntelHDMI) {
aml_add_string_buffer(pack, "onboard-2");
} else {
aml_add_string_buffer(pack, "onboard-1");
}
}
/*
if (!CustProperties(pack, DEV_HDMI)) {
DBG(" with default properties\n");
aml_add_string(pack, "layout-id");
aml_add_byte_buffer(pack, (CHAR8*)&GfxlayoutId[0], 4);
aml_add_string(pack, "PinConfigurations");
aml_add_byte_buffer(pack, data2, sizeof(data2));
}
*/
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root);
hdmi = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, hdmi, 0);
aml_destroy_node(root);
//insert HDAU
if (BridgeFound) { // bridge or lan
k = devadr1;
} else { //this is impossible
k = PCIADR;
}
Size = get_size(dsdt, k);
if (Size > 0) {
i = k + Size;
len = move_data(i, dsdt, len, sizeoffset);
CopyMem(dsdt + i, hdmi, sizeoffset);
j = write_size(k, dsdt, len, sizeoffset);
sizeoffset += j;
len += j;
len = CorrectOuters(dsdt, len, k-3, sizeoffset);
}
if (hdmi) {
FreePool(hdmi);
}
return len;
}
//Network -------------------------------------------------------------
UINT32 FIXNetwork (UINT8 *dsdt, UINT32 len, UINT32 card)
{
UINT32 i, k;
UINT32 NetworkADR = 0, BridgeSize, Size, BrdADR = 0;
UINT32 PCIADR, PCISIZE = 0;
INT32 sizeoffset;
AML_CHUNK *met, *met2;
AML_CHUNK *brd;
AML_CHUNK *root;
AML_CHUNK *pack;
AML_CHUNK *dev;
CHAR8 *network;
UINT32 FakeID = 0;
UINT32 FakeVen = 0;
CHAR8 NameCard[32];
if (!NetworkADR1[card]) return len;
DBG("Start NetWork %d Fix\n", card);
if (gSettings.FakeLAN) {
FakeID = gSettings.FakeLAN >> 16;
FakeVen = gSettings.FakeLAN & 0xFFFF;
AsciiSPrint(NameCard, 32, "pci%x,%x\0", FakeVen, FakeID);
LowCase(NameCard);
Netmodel[card] = get_net_model((FakeVen << 16) + FakeID);
}
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) return len; //what is the bad DSDT ?!
NetworkName = FALSE;
// Network Address
for (i = 0x24; len >=10 && i < len - 10; i++) {
if (CmpAdr(dsdt, i, NetworkADR1[card])) { //0x001C0004
BrdADR = devFind(dsdt, i);
if (!BrdADR) {
continue;
}
BridgeSize = get_size(dsdt, BrdADR);
if (!BridgeSize) {
continue;
}
if (NetworkADR2[card] != 0xFFFE){ //0
for (k = BrdADR + 9; k < BrdADR + BridgeSize; k++) {
if (CmpAdr(dsdt, k, NetworkADR2[card])) {
NetworkADR = devFind(dsdt, k);
if (!NetworkADR) {
continue;
}
device_name[1] = AllocateZeroPool(5);
CopyMem(device_name[1], dsdt+k, 4);
DBG("found NetWork device [0x%08x:%x] at %x and Name is %a\n",
NetworkADR1[card], NetworkADR2[card], NetworkADR, device_name[1]);
//renaming disabled until better way will found
// ReplaceName(dsdt + BrdADR, BridgeSize, device_name[1], "GIGE");
NetworkName = TRUE;
break;
}
}
if (!NetworkName) {
DBG("have no Network device while NetworkADR2=%x\n", NetworkADR2[card]);
//in this case NetworkADR point to bridge
NetworkADR = BrdADR;
}
} else {
NetworkADR = BrdADR;
}
break;
} // End if NetworkADR find
}
if (BrdADR) { // bridge or device
i = NetworkADR;
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_LAN) != 0) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in LAN already exists, dropped\n");
} else {
DBG("_DSM already exists, patch LAN will not be applied\n");
return len;
}
}
root = aml_create_node(NULL);
} else {
//what to do if no LAN bridge?
i = PCIADR;
brd = aml_create_node(NULL);
root = aml_add_device(brd, "LAN0");
aml_add_name(root, "_ADR");
aml_add_dword(root, NetworkADR1[card]);
DBG("Created bridge device with ADR=0x%x\n", NetworkADR1[card]);
}
DBG("NetworkADR1=%x NetworkADR2=%x\n", NetworkADR1[card], NetworkADR2[card]);
dev = root;
if (!NetworkName && (NetworkADR2[card] != 0xFFFE)) //there is no network device at dsdt, creating new one
{
dev = aml_add_device(root, NetName[card]);
aml_add_name(dev, "_ADR");
if (NetworkADR2[card]) {
if (NetworkADR2[card] > 0x3F)
aml_add_dword(dev, NetworkADR2[card]);
else
aml_add_byte(dev, (UINT8)NetworkADR2[card]);
} else {
aml_add_byte(dev, 0x00);
}
}
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_SUN");
if (k == 0) {
k = FindName(dsdt + i, Size, "_SUN");
if (k == 0) {
aml_add_name(dev, "_SUN");
aml_add_dword(dev, SlotDevices[5].SlotID);
} else {
//we have name sun, set the number
if (dsdt[k + 4] == 0x0A) {
dsdt[k + 5] = SlotDevices[5].SlotID;
}
}
}
// add Method(_DSM,4,NotSerialized) for network
if (gSettings.FakeLAN || !gSettings.NoDefaultProperties) {
met = aml_add_method(dev, "_DSM", 4);
met2 = aml_add_store(met);
pack = aml_add_package(met2);
aml_add_string(pack, "built-in");
aml_add_byte_buffer(pack, dataBuiltin, sizeof(dataBuiltin));
aml_add_string(pack, "model");
aml_add_string_buffer(pack, Netmodel[card]);
// aml_add_string(pack, "device_type");
// aml_add_string_buffer(pack, "Ethernet");
if (gSettings.FakeLAN) {
// aml_add_string(pack, "model");
// aml_add_string_buffer(pack, "Apple LAN card");
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, (CHAR8 *)&FakeID, 4);
aml_add_string(pack, "vendor-id");
aml_add_byte_buffer(pack, (CHAR8 *)&FakeVen, 4);
aml_add_string(pack, "name");
aml_add_string_buffer(pack, &NameCard[0]);
aml_add_string(pack, "compatible");
aml_add_string_buffer(pack, &NameCard[0]);
}
// Could we just comment this part? (Until remember what was the purposes?)
/* if (!CustProperties(pack, DEV_LAN) &&
!gSettings.FakeLAN &&
!gSettings.NoDefaultProperties) {
aml_add_string(pack, "empty");
aml_add_byte(pack, 0);
} */
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
}
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root);
network = AllocateZeroPool(root->Size);
if (!network) {
return len;
}
sizeoffset = root->Size;
DBG("network DSM created, size=%x\n", sizeoffset);
aml_write_node(root, network, 0);
aml_destroy_node(root);
if (NetworkADR) { // bridge or lan
i = NetworkADR;
} else { //this is impossible
i = PCIADR;
}
Size = get_size(dsdt, i);
// move data to back for add patch
k = i + Size;
len = move_data(k, dsdt, len, sizeoffset);
CopyMem(dsdt+k, network, sizeoffset);
// Fix Device network size
k = write_size(i, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, i-3, sizeoffset);
FreePool(network);
return len;
}
//Airport--------------------------------------------------
//CHAR8 dataBCM[] = {0x12, 0x43, 0x00, 0x00};
//CHAR8 data1ATH[] = {0x2a, 0x00, 0x00, 0x00};
//CHAR8 data2ATH[] = {0x8F, 0x00, 0x00, 0x00};
//CHAR8 data3ATH[] = {0x6B, 0x10, 0x00, 0x00};
UINT32 FIXAirport (UINT8 *dsdt, UINT32 len)
{
UINT32 i, k;
UINT32 ArptADR = 0, BridgeSize, Size, BrdADR = 0;
UINT32 PCIADR, PCISIZE = 0;
INT32 sizeoffset;
AML_CHUNK *met, *met2;
AML_CHUNK* brd;
AML_CHUNK* root;
AML_CHUNK* pack;
AML_CHUNK* dev;
CHAR8 *network;
UINT32 FakeID = 0;
UINT32 FakeVen = 0;
CHAR8 NameCard[32];
if (!ArptADR1) return len; // no device - no patch
if (gSettings.FakeWIFI) {
FakeID = gSettings.FakeWIFI >> 16;
FakeVen = gSettings.FakeWIFI & 0xFFFF;
AsciiSPrint(NameCard, 32, "pci%x,%x\0", FakeVen, FakeID);
LowCase(NameCard);
}
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) return len; //what is the bad DSDT ?!
DBG("Start Airport Fix\n");
ArptName = FALSE;
for (i=0x20; len >= 10 && i < len - 10; i++) {
// AirPort Address
if (CmpAdr(dsdt, i, ArptADR1) || CmpDev(dsdt, i, (UINT8*)gSettings.AirportBridgeDeviceName)) {
BrdADR = devFind(dsdt, i);
if (!BrdADR) {
continue;
}
BridgeSize = get_size(dsdt, BrdADR);
if(!BridgeSize) continue;
if (ArptADR2 != 0xFFFE){
for (k = BrdADR + 9; k < BrdADR + BridgeSize; k++) {
if (CmpAdr(dsdt, k, ArptADR2)) {
ArptADR = devFind(dsdt, k);
if (!ArptADR) {
continue;
}
device_name[9] = AllocateZeroPool(5);
CopyMem(device_name[9], dsdt+k, 4);
DBG("found Airport device [%08x:%x] at %x And Name is %a\n",
ArptADR1, ArptADR2, ArptADR, device_name[9]);
// ReplaceName(dsdt + BrdADR, BridgeSize, device_name[9], "ARPT"); //sometimes dangeous
ArptName = TRUE;
break;
}
}
}
break;
} // End ArptADR2
}
if (!ArptName) {
ArptADR = BrdADR;
}
if (BrdADR) { // bridge or device
i = ArptADR;
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_WIFI) != 0) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in ARPT already exists, dropped\n");
} else {
DBG("_DSM already exists, patch ARPT will not be applied\n");
return len;
}
}
root = aml_create_node(NULL);
}
//what to do if no Arpt bridge?
else {
brd = aml_create_node(NULL);
root = aml_add_device(brd, "ARP0");
aml_add_name(root, "_ADR");
aml_add_dword(root, ArptADR1);
DBG("Created bridge device with ADR=0x%x\n", ArptADR1);
}
dev = root;
if (!ArptName && (ArptADR2 != 0xFFFE)) {//there is no Airport device at dsdt, creating new one
dev = aml_add_device(root, "ARPT");
aml_add_name(dev, "_ADR");
if (ArptADR2) {
if (ArptADR2> 0x3F)
aml_add_dword(dev, ArptADR2);
else
aml_add_byte(dev, (UINT8)ArptADR2);
} else {
aml_add_byte(dev, 0x00);
}
}
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_SUN");
if (k == 0) {
k = FindName(dsdt + i, Size, "_SUN");
if (k == 0) {
aml_add_name(dev, "_SUN");
aml_add_dword(dev, SlotDevices[6].SlotID);
} else {
//we have name sun, set the number
if (dsdt[k + 4] == 0x0A) {
dsdt[k + 5] = SlotDevices[6].SlotID;
}
}
} else {
DBG("Warning: Method(_SUN) found for airport\n");
}
// add Method(_DSM,4,NotSerialized) for network
if (gSettings.FakeWIFI || !gSettings.NoDefaultProperties) {
met = aml_add_method(dev, "_DSM", 4);
met2 = aml_add_store(met);
pack = aml_add_package(met2);
if (!gSettings.NoDefaultProperties) {
aml_add_string(pack, "built-in");
aml_add_byte_buffer(pack, dataBuiltin, sizeof(dataBuiltin));
aml_add_string(pack, "model");
aml_add_string_buffer(pack, "Apple WiFi card");
aml_add_string(pack, "device_type");
aml_add_string_buffer(pack, "AirPort");
// aml_add_string(pack, "AAPL,slot-name");
// aml_add_string_buffer(pack, "AirPort");
}
if (gSettings.FakeWIFI) {
//aml_add_string(pack, "device-id");
//aml_add_byte_buffer(pack, (CHAR8 *)&FakeID, 4);
//aml_add_string(pack, "vendor-id");
//aml_add_byte_buffer(pack, (CHAR8 *)&FakeVen, 4);
aml_add_string(pack, "name");
aml_add_string_buffer(pack, (CHAR8 *)&NameCard[0]);
aml_add_string(pack, "compatible");
aml_add_string_buffer(pack, (CHAR8 *)&NameCard[0]);
}
if (!CustProperties(pack, DEV_WIFI) &&
!gSettings.NoDefaultProperties &&
!gSettings.FakeWIFI) {
aml_add_string(pack, "empty");
aml_add_byte(pack, 0);
}
aml_add_local0(met);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
}
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root);
network = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, network, 0);
aml_destroy_node(root);
DBG("AirportADR=%x add patch size=%x\n", ArptADR, sizeoffset);
if (ArptADR) { // bridge or WiFi
i = ArptADR;
} else { //this is impossible
i = PCIADR;
}
Size = get_size(dsdt, i);
DBG("adr %x size of arpt=%x\n", i, Size);
// move data to back for add patch
k = i + Size;
len = move_data(k, dsdt, len, sizeoffset);
CopyMem(dsdt+k, network, sizeoffset);
// Fix Device size
k = write_size(i, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, i-3, sizeoffset);
FreePool(network);
return len;
}
UINT32 FIXSBUS (UINT8 *dsdt, UINT32 len)
{
UINT32 i, k;
UINT32 SBUSADR=0, Size=0;
UINT32 PCIADR, PCISIZE = 0;
INT32 sizeoffset;
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) {
// DBG("wrong PCI0 address, patch SBUS will not be applied\n");
return len;
}
DBG("Start SBUS Fix PCI=%x len=%x\n", PCIADR, len);
// Find Device SBUS
if (SBUSADR1) {
for (i=0x20; len >= 10 && i < len - 10; i++) {
if (CmpAdr(dsdt, i, SBUSADR1))
{
SBUSADR = devFind(dsdt, i);
if (SBUSADR) {
DBG("device (SBUS) found at %x\n", SBUSADR);
break;
}
} // end SBUS
}
}
if (SBUSADR) { // bridge or device
i = SBUSADR;
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_SMBUS) != 0) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in SBUS already exists, dropped\n");
} else {
DBG("_DSM already exists, patch SBUS will not be applied\n");
return len;
}
}
Size = get_size(dsdt, SBUSADR);
if (ReplaceName(dsdt + SBUSADR, Size, NULL, "BUS0") < 0) {
DBG("BUS0 already exists, patch SBUS will not be applied\n");
return len;
}
}
if (SBUSADR)
sizeoffset = sizeof(bus0);
else
sizeoffset = sizeof(sbus1);
// DBG("SBUS address %x code size = 0x%08x\n", SBUSADR, sizeoffset);
if (SBUSADR) {
// move data to back for add sbus
Size = get_size(dsdt, SBUSADR);
i = SBUSADR + Size;
len = move_data(i, dsdt, len, sizeoffset);
CopyMem(dsdt+i, bus0, sizeoffset);
// Fix Device sbus size
k = write_size(SBUSADR, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, SBUSADR-3, sizeoffset);
// SBUSADR = adr1;
DBG("SBUS code size fix = 0x%08x\n", sizeoffset);
} else {
PCISIZE = get_size(dsdt, PCIADR);
i = PCIADR + PCISIZE;
DBG("SBUS absent, adding to the end of PCI0 at %x\n", i);
len = move_data(i, dsdt, len, sizeoffset);
CopyMem(dsdt+i, sbus1, sizeoffset);
// Fix PCIX size
k = write_size(PCIADR, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, PCIADR-3, sizeoffset);
}
return len;
}
//CHAR8 dataMCHC[] = {0x44,0x00,0x00,0x00};
UINT32 AddMCHC (UINT8 *dsdt, UINT32 len)
{
UINT32 i, k = 0;
UINT32 PCIADR, PCISIZE = 0; //, Size;
INT32 sizeoffset;
AML_CHUNK *root;
AML_CHUNK *device;
// AML_CHUNK *met, *met2;
// AML_CHUNK *pack;
CHAR8 *mchc;
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) {
// DBG("wrong PCI0 address, patch MCHC will not be applied\n");
return len;
}
//Find Device MCHC by name
for (i=0x20; len >= 10 && i < len - 10; i++) {
k = CmpDev(dsdt, i, (UINT8*)"MCHC");
if (k != 0) {
DBG("device name (MCHC) found at %x, don't add!\n", k);
// break;
return len;
}
}
DBG("Start Add MCHC\n");
root = aml_create_node(NULL);
//Slice - now I don\t want to add _DSM to MCHC
//as far as I understand it works only for native ID, not FakeID.
/* if (!k) {
//device not found
device = aml_add_device(root, "MCHC");
aml_add_name(device, "_ADR");
aml_add_byte(device, 0x00);
met = aml_add_method(device, "_DSM", 4);
} else {
//if device present then check _DSM
Size = get_size(dsdt, k);
i = FindMethod(dsdt + k, Size, "_DSM");
if (i != 0) {
DBG("found MCHC with DSM, patch is not needed\n");
return len;
}
met = aml_add_method(root, "_DSM", 4);
}
*/
device = aml_add_device(root, "MCHC");
aml_add_name(device, "_ADR");
aml_add_byte(device, 0x00);
// add Method(_DSM,4,NotSerialized) for MCHC
/*
met2 = aml_add_store(met);
pack = aml_add_package(met2);
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, dataMCHC, sizeof(dataMCHC));
aml_add_string(pack, "name");
aml_add_string(pack, "pci8086,44");
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
// finish Method(_DSM,4,NotSerialized)
*/
aml_calculate_size(root);
mchc = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, mchc, 0);
aml_destroy_node(root);
// always add on PCIX back
PCISIZE = get_size(dsdt, PCIADR);
len = move_data(PCIADR + PCISIZE, dsdt, len, sizeoffset);
CopyMem(dsdt + PCIADR + PCISIZE, mchc, sizeoffset);
// Fix PCIX size
k = write_size(PCIADR, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, PCIADR-3, sizeoffset);
FreePool(mchc);
return len;
}
UINT32 AddIMEI (UINT8 *dsdt, UINT32 len)
{
UINT32 i, k = 0;
UINT32 PCIADR, PCISIZE = 0;
INT32 sizeoffset;
AML_CHUNK *root;
AML_CHUNK *device;
AML_CHUNK *met, *met2;
AML_CHUNK *pack;
CHAR8 *imei;
UINT32 FakeID;
UINT32 FakeVen;
if (gSettings.FakeIMEI) {
FakeID = gSettings.FakeIMEI >> 16;
FakeVen = gSettings.FakeIMEI & 0xFFFF;
}
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) {
// DBG("wrong PCI0 address, patch IMEI will not be applied\n");
return len;
}
// Find Device IMEI
if (IMEIADR1) {
for (i=0x20; len >= 10 && i < len - 10; i++) {
if (CmpAdr(dsdt, i, IMEIADR1)) {
k = devFind(dsdt, i);
if (k) {
MsgLog("device (IMEI) found at %x, don't add!\n", k);
// break;
return len;
}
}
}
}
//Find Device IMEI by name
for (i=0x20; len >= 10 && i < len - 10; i++) {
k = CmpDev(dsdt, i, (UINT8*)"IMEI");
if (k != 0) {
MsgLog("device name (IMEI) found at %x, don't add!\n", k);
return len;
}
}
MsgLog("Start Add IMEI\n");
root = aml_create_node(NULL);
device = aml_add_device(root, "IMEI");
aml_add_name(device, "_ADR");
aml_add_dword(device, IMEIADR1);
// add Method(_DSM,4,NotSerialized)
if (gSettings.FakeIMEI) {
met = aml_add_method(device, "_DSM", 4);
met2 = aml_add_store(met);
pack = aml_add_package(met2);
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeID, 4);
aml_add_string(pack, "vendor-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeVen, 4);
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
// finish Method(_DSM,4,NotSerialized)
}
aml_calculate_size(root);
imei = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, imei, 0);
aml_destroy_node(root);
// always add on PCIX back
len = move_data(PCIADR+PCISIZE, dsdt, len, sizeoffset);
CopyMem(dsdt+PCIADR+PCISIZE, imei, sizeoffset);
// Fix PCIX size
k = write_size(PCIADR, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, PCIADR-3, sizeoffset);
FreePool(imei);
return len;
}
CHAR8 dataFW[] = {0x00,0x00,0x00,0x00};
UINT32 FIXFirewire (UINT8 *dsdt, UINT32 len)
{
UINT32 i, k;
UINT32 FirewireADR = 0, BrdADR = 0, BridgeSize, Size;
INT32 sizeoffset;
UINT32 PCIADR, PCISIZE = 0;
AML_CHUNK *met;
AML_CHUNK *root;
AML_CHUNK *stro;
AML_CHUNK *pack;
CHAR8 *firewire;
AML_CHUNK* device;
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) {
DBG("wrong PCI0 address, patch FRWR will not be applied\n");
return len;
}
// Firewire Address
for (i = 0x20; len >=10 && i < len - 10; i++) {
if (FirewireADR1 != 0x00000000 &&
CmpAdr(dsdt, i, FirewireADR1)) {
BrdADR = devFind(dsdt, i);
if (!BrdADR) {
continue;
}
BridgeSize = get_size(dsdt, BrdADR);
if (FirewireADR2 != 0xFFFE ){
for (k = BrdADR + 9; k < BrdADR + BridgeSize; k++) {
if (CmpAdr(dsdt, k, FirewireADR2)) {
FirewireADR = devFind(dsdt, k);
if (!FirewireADR) {
continue;
}
device_name[2] = AllocateZeroPool(5);
CopyMem(device_name[2], dsdt+k, 4);
DBG("found Firewire device NAME(_ADR,0x%08x) at %x And Name is %a\n",
FirewireADR2, k, device_name[2]);
ReplaceName(dsdt + BrdADR, BridgeSize, device_name[2], "FRWR");
FirewireName = TRUE;
break;
}
}
}
break;
} // End Firewire
}
if (!BrdADR) {
DBG("Bridge for FRWR is not found\n");
return len;
}
//safe for twice fix: if _DSM already present then cancel fix
if (FirewireADR) { // bridge or device
i = FirewireADR;
} else {
i = BrdADR;
}
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_FIREWIRE) != 0) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in FRWR already exists, dropped\n");
} else {
DBG("_DSM already exists, patch FRWR will not be applied\n");
return len;
}
}
root = aml_create_node(NULL);
device = root;
DBG("Start Firewire Fix\n");
if (!FirewireName) {
device = aml_add_device(root, "FRWR");
aml_add_name(device, "_ADR");
if (FirewireADR2) {
if (FirewireADR2 <= 0x3F) {
aml_add_byte(device, (UINT8)FirewireADR2);
} else {
aml_add_dword(device, FirewireADR2);
}
} else aml_add_byte(device, 0);
aml_add_name(device, "_GPE");
aml_add_byte(device, 0x1A);
}
met = aml_add_method(device, "_DSM", 4);
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_SUN");
if (k == 0) {
k = FindName(dsdt + i, Size, "_SUN");
if (k == 0) {
aml_add_name(device, "_SUN");
aml_add_dword(device, SlotDevices[12].SlotID);
} else {
//we have name sun, set the number
if (dsdt[k + 4] == 0x0A) {
dsdt[k + 5] = SlotDevices[12].SlotID;
}
}
} else {
DBG("Warning: Method(_SUN) found for firewire\n");
}
stro = aml_add_store(met);
pack = aml_add_package(stro);
if (!CustProperties(pack, DEV_FIREWIRE)) {
aml_add_string(pack, "fwhub");
aml_add_byte_buffer(pack, dataFW, sizeof(dataFW));
}
aml_add_local0(stro);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root);
firewire = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, firewire, 0);
aml_destroy_node(root);
// move data to back for add patch
Size = get_size(dsdt, i);
if (!Size) {
FreePool(firewire);
return len;
}
k = i + Size;
len = move_data(k, dsdt, len, sizeoffset);
CopyMem(dsdt + k, firewire, sizeoffset);
// Fix Device size
k = write_size(i, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, i-3, sizeoffset);
FreePool(firewire);
return len;
}
UINT32 AddHDEF (UINT8 *dsdt, UINT32 len, CHAR8* OSVersion)
{
UINT32 i, k;
UINT32 PCIADR, PCISIZE = 0;
INT32 sizeoffset;
UINT32 HDAADR = 0, Size;
AML_CHUNK* root;
// AML_CHUNK* met, *met2;
AML_CHUNK* device;
// AML_CHUNK* pack;
CHAR8 *hdef;
PCIADR = GetPciDevice(dsdt, len);
if (PCIADR) {
PCISIZE = get_size(dsdt, PCIADR);
}
if (!PCISIZE) return len; //what is the bad DSDT ?!
DBG("Start HDA Fix\n");
// len = DeleteDevice("AZAL", dsdt, len);
// HDA Address
for (i=0x20; len >= 10 && i < len - 10; i++) {
if (HDAADR1 != 0x00000000 && HDAFIX &&
CmpAdr(dsdt, i, HDAADR1)) {
HDAADR = devFind(dsdt, i);
if (!HDAADR) {
continue;
}
// BridgeSize = get_size(dsdt, HDAADR);
device_name[4] = AllocateZeroPool(5);
CopyMem(device_name[4], dsdt+i, 4);
DBG("found HDA device NAME(_ADR,0x%08x) And Name is %a\n",
HDAADR1, device_name[4]);
ReplaceName(dsdt, len, device_name[4], "HDEF");
HDAFIX = FALSE;
break;
} // End HDA
}
if (HDAADR) { // bridge or device
i = HDAADR;
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_HDA) != 0) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in HDA already exists, dropped\n");
} else {
DBG("_DSM already exists, patch HDA will not be applied\n");
return len;
}
}
}
root = aml_create_node(NULL);
if (HDAFIX) {
MsgLog("Start Add Device HDEF\n");
device = aml_add_device(root, "HDEF");
aml_add_name(device, "_ADR");
aml_add_dword(device, HDAADR1);
// add Method(_DSM,4,NotSerialized)
/* met = aml_add_method(device, "_DSM", 4);
} else {
met = aml_add_method(root, "_DSM", 4);
}
met2 = aml_add_store(met);
pack = aml_add_package(met2);
if (gSettings.UseIntelHDMI) {
aml_add_string(pack, "hda-gfx");
aml_add_string_buffer(pack, "onboard-1");
}
if (!CustProperties(pack, DEV_HDA)) {
if ((OSVersion != NULL && AsciiOSVersionToUint64(OSVersion) < AsciiOSVersionToUint64("10.8")) || (gSettings.HDALayoutId > 0)) {
aml_add_string(pack, "layout-id");
aml_add_byte_buffer(pack, (CHAR8*)&HDAlayoutId, 4);
}
aml_add_string(pack, "MaximumBootBeepVolume");
aml_add_byte_buffer(pack, (CHAR8*)&dataBuiltin1[0], 1);
if (gSettings.AFGLowPowerState) {
aml_add_string(pack, "AFGLowPowerState");
aml_add_byte_buffer(pack, Yes, 4);
}
aml_add_string(pack, "PinConfigurations");
aml_add_byte_buffer(pack, 0, 0);//data, sizeof(data));
}
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
// finish Method(_DSM,4,NotSerialized)
*/
}
aml_calculate_size(root);
hdef = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, hdef, 0);
aml_destroy_node(root);
if (!HDAFIX) { // bridge or device
i = HDAADR;
} else {
i = PCIADR;
}
Size = get_size(dsdt, i);
// move data to back for add patch
k = i + Size;
len = move_data(k, dsdt, len, sizeoffset);
CopyMem(dsdt + k, hdef, sizeoffset);
// Fix Device size
k = write_size(i, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, i-3, sizeoffset);
FreePool(hdef);
return len;
}
UINT32 FIXUSB (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j, k;
UINT32 Size, size1, size2, size3; //, size4;
UINT32 adr=0, adr1=0;
INT32 sizeoffset;
AML_CHUNK* root;
AML_CHUNK* root1;
AML_CHUNK* met;
AML_CHUNK* pack;
AML_CHUNK *met1, *met2;
AML_CHUNK* pack1;
CHAR8 *USBDATA1;
CHAR8 *USBDATA2;
CHAR8 *USBDATA3;
// CHAR8 *USBDATA4;
DBG("Start USB Fix\n");
//DBG("len = 0x%08x\n", len);
root = aml_create_node(NULL);
root1 = aml_create_node(NULL);
// add Method(_DSM,4,NotSerialized) for USB
met = aml_add_method(root, "_DSM", 4);
met2 = aml_add_store(met);
pack = aml_add_package(met2);
if (!CustProperties(pack, DEV_USB)) {
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, (/* CONST*/ CHAR8*)&USBID[0], 4);
aml_add_string(pack, "built-in");
aml_add_byte_buffer(pack, dataBuiltin, sizeof(dataBuiltin));
aml_add_string(pack, "device_type");
if (USBIntel) {
aml_add_string_buffer(pack, "UHCI");
} else if (USBNForce) {
aml_add_string_buffer(pack, "OHCI");
}
if (gSettings.InjectClockID) {
aml_add_string(pack, "AAPL,clock-id");
aml_add_byte_buffer(pack, dataBuiltin, 1);
}
}
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root);
USBDATA1 = AllocateZeroPool(root->Size);
size1 = root->Size;
// DBG("USB1 code size = 0x%08x\n", size1);
aml_write_node(root, USBDATA1, 0);
aml_destroy_node(root);
// add Method(_DSM,4,NotSerialized) for USB2
met1 = aml_add_method(root1, "_DSM", 4);
met2 = aml_add_store(met1);
pack1 = aml_add_package(met2);
if (!CustProperties(pack, DEV_USB)) {
aml_add_string(pack1, "device-id");
aml_add_byte_buffer(pack1, (/* CONST*/ CHAR8*)&USBID[0], 4);
aml_add_string(pack1, "built-in");
aml_add_byte_buffer(pack1, dataBuiltin, sizeof(dataBuiltin));
aml_add_string(pack1, "device_type");
aml_add_string_buffer(pack1, "EHCI");
if (gSettings.InjectClockID) {
aml_add_string(pack1, "AAPL,clock-id");
aml_add_byte_buffer(pack1, dataBuiltin, sizeof(dataBuiltin));
}
if (USBIntel) {
aml_add_string(pack1, "AAPL,current-available");
if (gSettings.HighCurrent) {
aml_add_word(pack1, 0x0834);
} else {
aml_add_word(pack1, 0x05DC);
}
aml_add_string(pack1, "AAPL,current-extra");
if (gSettings.HighCurrent) {
aml_add_word(pack1, 0x0C80);
} else {
aml_add_word(pack1, 0x03E8);
}
aml_add_string(pack1, "AAPL,current-in-sleep");
aml_add_word(pack1, 0x0BB8);
// aml_add_string(pack1, "AAPL,device-internal");
// aml_add_byte(pack1, 0x02);
} else if (USBNForce) {
aml_add_string(pack1, "AAPL,current-available");
aml_add_word(pack1, 0x04B0);
aml_add_string(pack1, "AAPL,current-extra");
aml_add_word(pack1, 0x02BC);
aml_add_string(pack1, "AAPL,current-in-sleep");
aml_add_word(pack1, 0x03E8);
}
}
//new systems has new strings
/*
Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method
{
Store (Package (0x08)
{
"kUSBSleepPowerSupply",
0x13EC,
"kUSBSleepPortCurrentLimit",
0x0834,
"kUSBWakePowerSupply",
0x13EC,
"kUSBWakePortCurrentLimit",
0x0834
}, Local0)
DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
Return (Local0)
}
*/
aml_add_byte_buffer(pack1, dataBuiltin, sizeof(dataBuiltin));
aml_add_local0(met2);
aml_add_buffer(met1, dtgp_1, sizeof(dtgp_1));
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root1);
USBDATA2 = AllocateZeroPool(root1->Size);
size2 = root1->Size;
// DBG("USB2 code size = 0x%08x\n", size2);
aml_write_node(root1, USBDATA2, 0);
aml_destroy_node(root1);
//NFORCE_USB_START -- already done Intel or NForce same USBDATA2
/* aml_calculate_size(root1);
USBDATA4 = AllocateZeroPool(root1->Size);
size4 = root1->Size;
DBG("USB OHCI code size = 0x%08x\n", size4);
aml_write_node(root1, USBDATA4, 0);
aml_destroy_node(root1); */
//NFORCE_USB_END
// add Method(_DSM,4,NotSerialized) for USB3
root1 = aml_create_node(NULL);
met1 = aml_add_method(root1, "_DSM", 4);
met2 = aml_add_store(met1);
pack1 = aml_add_package(met2);
if (!CustProperties(pack, DEV_USB)) {
aml_add_string(pack1, "device-id");
aml_add_byte_buffer(pack1, (/* CONST*/ CHAR8*)&USBID[0], 4);
aml_add_string(pack1, "built-in");
aml_add_byte_buffer(pack1, dataBuiltin, sizeof(dataBuiltin));
aml_add_string(pack1, "device_type");
aml_add_string_buffer(pack1, "XHCI");
if (gSettings.InjectClockID) {
aml_add_string(pack1, "AAPL,clock-id");
aml_add_byte_buffer(pack1, dataBuiltin, sizeof(dataBuiltin));
}
aml_add_string(pack1, "AAPL,current-available");
aml_add_word(pack1, 0x0834);
aml_add_string(pack1, "AAPL,current-extra");
aml_add_word(pack1, 0x0A8C);
aml_add_string(pack1, "AAPL,current-in-sleep");
aml_add_word(pack1, 0x0A8C);
aml_add_string(pack1, "AAPL,max-port-current-in-sleep");
aml_add_word(pack1, 0x0834);
aml_add_string(pack1, "AAPL,device-internal");
aml_add_byte(pack1, 0x00);
}
aml_add_byte_buffer(pack1, dataBuiltin, sizeof(dataBuiltin));
aml_add_local0(met2);
aml_add_buffer(met1, dtgp_1, sizeof(dtgp_1));
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root1);
USBDATA3 = AllocateZeroPool(root1->Size);
size3 = root1->Size;
// DBG("USB3 code size = 0x%08x\n", size3);
aml_write_node(root1, USBDATA3, 0);
aml_destroy_node(root1);
if (usb > 0) {
for (i = 0; i < usb; i++) {
INTN XhciCount = 1;
INTN EhciCount = 0;
// find USB adr
for (j = 0x20; len >= 4 && j < len - 4; j++) {
if (CmpAdr(dsdt, j, USBADR[i])) { //j+4 -> _ADR
XhciName = FALSE;
UsbName[i] = AllocateZeroPool(5);
// DBG("found USB at 0x%x\n", j);
adr1 = devFind(dsdt, j + 2);
if (!adr1) {
continue;
}
Size = get_size(dsdt, adr1); //bridgesize
DBG("USB bridge[%x] at %x, size = %x\n", USBADR[i], adr1, Size);
if (USBADR2[i] != 0xFFFE ){
for (k = adr1 + 9; k < adr1 + Size; k++) {
if (CmpAdr(dsdt, k, USBADR2[i])) {
adr = devFind(dsdt, k);
if (!adr) {
continue;
}
device_name[10] = AllocateZeroPool(5);
CopyMem(device_name[10], dsdt+k, 4);
DBG("found USB device [%08x:%x] at %x and Name was %a ->",
USBADR[i], USBADR2[i], k, device_name[10]);
if (USB30[i]) {
if (gSettings.NameXH00) {
AsciiSPrint(UsbName[i], 5, "XH%02X", XhciCount++);
} else {
AsciiSPrint(UsbName[i], 5, "XHC%01X", XhciCount++);
}
} else if (USB20[i]) {
if (gSettings.NameEH00) {
AsciiSPrint(UsbName[i], 5, "EH%02X", EhciCount++);
} else {
AsciiSPrint(UsbName[i], 5, "EHC%01X", EhciCount++);
}
} else {
AsciiSPrint(UsbName[i], 5, "USB%d", i);
}
DBG(" %a\n", UsbName[i]);
ReplaceName(dsdt + adr1, Size, device_name[10], UsbName[i]);
XhciName = TRUE;
break;
}
}
}
if (!XhciName) {
adr = adr1;
}
Size = get_size(dsdt, adr);
k = FindMethod(dsdt + adr, Size, "_DSM");
if (k != 0) {
k += adr;
//here we want to check who is the master of the _DSM
adr1 = devFind(dsdt, k);
if (adr1 == adr) {
if ((dropDSM & DEV_USB) != 0) {
Size = get_size(dsdt, k);
if (!Size) {
continue;
}
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in USB already exists, dropped by 0x%x\n", sizeoffset);
} else {
DBG("_DSM already exists, patch USB will not be applied\n");
continue;
}
} else {
DBG(" found slave _DSM, skip\n");
continue;
}
}
//UINT32 k = (adr > 0x3F)?1:0;
/*
14 45 06 5F 44 53 4D 04 70 12 4F 04 08 0D 64 65
76 69 63 65 2D 69 64 00 11 07 0A 04 31 1E 00 00
0D 62 75 69 6C 74 2D 69 6E 00 11 04 0A 01 00 0D
64 65 76 69 63 65 5F 74 79 70 65 00 11 08 0A 04
55 48 43 49 00 0D 41 41 50 4C 2C 63 6C 6F 63 6B
2D 69 64 00 11 04 0A 01 00 60 44 54 47 50 68 69
6A 6B 71 60 A4 60
*/
if (USB30[i]) {
if ((USBDATA3[25] == 0x0A) && (USBDATA3[26] == 0x04)) {
k = 27;
} else if ((USBDATA3[26] == 0x0A) && (USBDATA3[27] == 0x04)) {
k = 28;
} else {
continue;
}
if (gSettings.FakeXHCI) {
USBID[i] = gSettings.FakeXHCI >> 16;
}
CopyMem(USBDATA3+k, (VOID*)&USBID[i], 4);
sizeoffset = size3;
} else if (USB20[i]) {
if ((USBDATA2[25] == 0x0A) && (USBDATA2[26] == 0x04)) {
k = 27;
} else if ((USBDATA2[26] == 0x0A) && (USBDATA2[27] == 0x04)) {
k = 28;
} else {
continue;
}
CopyMem(USBDATA2+k, (VOID*)&USBID[i], 4);
sizeoffset = size2;
} else {
if ((USBDATA1[25] == 0x0A) && (USBDATA1[26] == 0x04)) {
k = 27;
} else if ((USBDATA1[26] == 0x0A) && (USBDATA1[27] == 0x04)) {
k = 28;
} else {
continue;
}
CopyMem(USBDATA1+k, (VOID*)&USBID[i], 4);
sizeoffset = size1;
}
len = move_data(adr + Size, dsdt, len, sizeoffset);
if (USB30[i]) {
CopyMem(dsdt + adr + Size, USBDATA3, sizeoffset);
} else if (USB20[i]) {
CopyMem(dsdt + adr + Size, USBDATA2, sizeoffset);
} else {
CopyMem(dsdt + adr + Size, USBDATA1, sizeoffset);
}
// Fix Device USB size
k = write_size(adr, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, adr-3, sizeoffset);
break;
}
//NFORCE_USB_START
else if (CmpAdr(dsdt, j, USBADR3[i])) {
UsbName[i] = AllocateZeroPool(5);
CopyMem(UsbName[i], dsdt+j, 4);
adr1 = devFind(dsdt, j);
if (!adr1) {
continue;
}
adr = get_size(dsdt, adr1);
//UINT32 k = (adr > 0x3F)?1:0;
/*
14 45 06 5F 44 53 4D 04 70 12 4F 04 08 0D 64 65
76 69 63 65 2D 69 64 00 11 07 0A 04 31 1E 00 00
0D 62 75 69 6C 74 2D 69 6E 00 11 04 0A 01 00 0D
64 65 76 69 63 65 5F 74 79 70 65 00 11 08 0A 04
55 48 43 49 00 0D 41 41 50 4C 2C 63 6C 6F 63 6B
2D 69 64 00 11 04 0A 01 00 60 44 54 47 50 68 69
6A 6B 71 60 A4 60
*/
if (USB40[i]) {
if ((USBDATA2[25] == 0x0A) && (USBDATA2[26] == 0x04)) {
k = 27;
} else if ((USBDATA2[26] == 0x0A) && (USBDATA2[27] == 0x04)) {
k = 28;
} else {
continue;
}
CopyMem(USBDATA2+k, (VOID*)&USBID[i], 4);
sizeoffset = size2;
} else {
if ((USBDATA1[25] == 0x0A) && (USBDATA1[26] == 0x04)) {
k = 27;
} else if ((USBDATA1[26] == 0x0A) && (USBDATA1[27] == 0x04)) {
k = 28;
} else {
continue;
}
CopyMem(USBDATA1+k, (VOID*)&USBID[i], 4);
sizeoffset = size1;
}
len = move_data(adr1+adr, dsdt, len, sizeoffset);
if (USB40[i]) {
CopyMem(dsdt+adr1+adr, USBDATA2, sizeoffset);
} else {
CopyMem(dsdt+adr1+adr, USBDATA1, sizeoffset);
}
// Fix Device USB size
k = write_size(adr1, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, adr1-3, sizeoffset);
break;
}
//NFORCE_USB_END
}
}
}
FreePool(USBDATA1);
FreePool(USBDATA2);
FreePool(USBDATA3);
// FreePool(USBDATA4);
return len;
}
CHAR8 DevIDE[] = {0x9E,0x26,0x00,0x00};
CHAR8 VenIDE[] = {0x86,0x80,0x00,0x00};
UINT32 FIXIDE (UINT8 *dsdt, UINT32 len)
{
UINT32 i, k;
UINT32 j;
UINT32 IDEADR = 0, BridgeSize = 0, Size;
INT32 sizeoffset;
AML_CHUNK *root;
AML_CHUNK *device;
CHAR8 *ide;
BOOLEAN PATAFIX=TRUE;
AML_CHUNK *met, *met2;
AML_CHUNK *pack;
AML_CHUNK *device1;
AML_CHUNK *device2;
if (!IDEADR1) return len;
for (i=0x20; len >= 10 && i < len - 10; i++) {
if (CmpAdr(dsdt, i, IDEADR1)) {
DBG("Found IDEADR1=%x at %x\n", IDEADR1, i);
IDEADR = devFind(dsdt, i);
if (!IDEADR) {
continue;
}
BridgeSize = get_size(dsdt, IDEADR);
if (BridgeSize) break;
} // End IDE
}
if (!BridgeSize) return len;
DBG("Start IDE Fix\n");
// find Name(_ADR, Zero) if yes, don't need to inject PATA name
for (j=IDEADR+9; j<IDEADR+BridgeSize; j++)
{
if (CmpAdr(dsdt, j, 0))
{
PATAFIX = FALSE;
break;
}
}
if (IDEADR) { // bridge or device
i = IDEADR;
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_IDE) != 0) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in IDE already exists, dropped\n");
} else {
DBG("_DSM already exists, patch IDE will not be applied\n");
return len;
}
}
}
root = aml_create_node(NULL);
device = root;
if (PATAFIX) {
device = aml_add_device(root, "ICHX");
aml_add_name(device, "_ADR");
if (IDEADR2 < 0x3F) {
aml_add_byte(device, (UINT8)IDEADR2);
} else {
aml_add_dword(device, IDEADR2);
}
met = aml_add_method(device, "_DSM", 4);
met2 = aml_add_store(met);
pack = aml_add_package(met2);
if (!CustProperties(pack, DEV_IDE)) {
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, DevIDE, sizeof(DevIDE));
aml_add_string(pack, "vendor-id");
aml_add_byte_buffer(pack, VenIDE, sizeof(VenIDE));
aml_add_string(pack, "name");
aml_add_string(pack, "pci8086,269e");
aml_add_string(pack, "IOName");
aml_add_string(pack, "pci8086,269e");
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
device1 = aml_add_device(device, "PRIM");
aml_add_name(device1, "_ADR");
aml_add_byte(device1, 0x00);
device2 = aml_add_device(device1, "MAST");
aml_add_name(device2, "_ADR");
aml_add_byte(device2, 0x00);
device2 = aml_add_device(device1, "SLAV");
aml_add_name(device2, "_ADR");
aml_add_byte(device2, 0x01);
// Marvell only one connected cable
//AML_CHUNK* device3 = aml_add_device(device, "SLAB");
//aml_add_name(device3, "_ADR");
//aml_add_byte(device3, 0x00);
//AML_CHUNK* device4 = aml_add_device(device3, "MAST");
//aml_add_name(device4, "_ADR");
//aml_add_byte(device4, 0x00);
//device4 = aml_add_device(device3, "SLAV");
//aml_add_name(device4, "_ADR");
//aml_add_byte(device4, 0x01);
aml_add_string(met, "empty");
aml_add_byte(met, 0);
}
} else {
met = aml_add_method(root, "_DSM", 4);
met2 = aml_add_store(met);
pack = aml_add_package(met2);
if (!CustProperties(pack, DEV_IDE)) {
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, DevIDE, sizeof(DevIDE));
aml_add_string(pack, "vendor-id");
aml_add_byte_buffer(pack, VenIDE, sizeof(VenIDE));
aml_add_string(pack, "name");
aml_add_string(pack, "pci8086,269e");
aml_add_string(pack, "IOName");
aml_add_string(pack, "pci8086,269e");
aml_add_string(met, "empty");
aml_add_byte(met, 0);
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
}
}
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root);
ide = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, ide, 0);
aml_destroy_node(root);
// move data to back for add DSM
j = IDEADR + BridgeSize;
len = move_data(j, dsdt, len, sizeoffset);
CopyMem(dsdt+j, ide, sizeoffset);
// Fix Device ide size
k = write_size(IDEADR, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, IDEADR-3, sizeoffset);
//add patafix
sizeoffset = sizeof(patafix);
// DBG("add patafix size=%x\n", sizeoffset);
i = get_size(dsdt, IDEADR);
j = IDEADR + i;
len = move_data(j, dsdt, len, sizeoffset);
CopyMem(dsdt+j, patafix, sizeoffset);
k = write_size(IDEADR, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, IDEADR-3, sizeoffset);
FreePool(ide);
return len;
}
//CHAR8 DevSATA[] = {0x81, 0x26, 0x00, 0x00};
UINT32 FIXSATAAHCI (UINT8 *dsdt, UINT32 len)
{
UINT32 i, k;
UINT32 SATAAHCIADR = 0, BridgeSize = 0, Size;
INT32 sizeoffset;
AML_CHUNK* root;
AML_CHUNK* met, *met2;
AML_CHUNK* pack;
CHAR8 *sata;
UINT32 FakeID;
UINT32 FakeVen;
if (gSettings.FakeSATA) {
FakeID = gSettings.FakeSATA >> 16;
FakeVen = gSettings.FakeSATA & 0xFFFF;
}
if (!SATAAHCIADR1) return len;
for (i=0x20; len >= 10 && i < len - 10; i++) {
if (CmpAdr(dsdt, i, SATAAHCIADR1)) {
// DBG("Found SATAAHCIADR1=%x at %x\n", SATAAHCIADR1, i);
SATAAHCIADR = devFind(dsdt, i);
if (!SATAAHCIADR) {
continue;
}
BridgeSize = get_size(dsdt, SATAAHCIADR);
if (BridgeSize) break;
}
}
if (!BridgeSize) return len;
if (SATAAHCIADR) { // bridge or device
i = SATAAHCIADR;
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_SATA) != 0) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in SATA already exists, dropped\n");
} else {
DBG("_DSM already exists, patch SATA will not be applied\n");
return len;
}
}
}
DBG("Start SATA AHCI Fix\n");
root = aml_create_node(NULL);
// add Method(_DSM,4,NotSerialized)
if (gSettings.FakeSATA || !gSettings.NoDefaultProperties) {
met = aml_add_method(root, "_DSM", 4);
met2 = aml_add_store(met);
pack = aml_add_package(met2);
if (gSettings.FakeSATA) {
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeID, 4);
aml_add_string(pack, "vendor-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeVen, 4);
}
if (!CustProperties(pack, DEV_SATA) &&
!gSettings.NoDefaultProperties &&
!gSettings.FakeSATA) {
aml_add_string(pack, "empty");
aml_add_byte(pack, 0);
}
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
}
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root);
sata = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, sata, 0);
aml_destroy_node(root);
// move data to back for add DSM
BridgeSize = get_size(dsdt, SATAAHCIADR);
i = SATAAHCIADR + BridgeSize;
len = move_data(i, dsdt, len, sizeoffset);
CopyMem(dsdt + i, sata, sizeoffset);
// Fix Device SATA size
k = write_size(SATAAHCIADR, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, SATAAHCIADR-3, sizeoffset);
FreePool(sata);
return len;
}
//CHAR8 DevSATA0[] = {0x80, 0x26, 0x00, 0x00};
UINT32 FIXSATA (UINT8 *dsdt, UINT32 len)
{
UINT32 i, k;
UINT32 SATAADR = 0, BridgeSize = 0, Size;
INT32 sizeoffset;
AML_CHUNK* root;
AML_CHUNK* met, *met2;
AML_CHUNK* pack;
CHAR8 *sata;
UINT32 FakeID;
UINT32 FakeVen;
if (gSettings.FakeSATA) {
FakeID = gSettings.FakeSATA >> 16;
FakeVen = gSettings.FakeSATA & 0xFFFF;
}
if (!SATAADR1) return len;
for (i=0x20; len >= 10 && i < len - 10; i++) {
if (CmpAdr(dsdt, i, SATAADR1)) {
// DBG("Found SATAAHCIADR1=%x at %x\n", SATAAHCIADR1, j);
SATAADR = devFind(dsdt, i);
if (!SATAADR) {
continue;
}
BridgeSize = get_size(dsdt, SATAADR);
if (BridgeSize) break;
} // End IDE
}
if (!BridgeSize) return len;
if (SATAADR) { // bridge or device
i = SATAADR;
Size = get_size(dsdt, i);
k = FindMethod(dsdt + i, Size, "_DSM");
if (k != 0) {
k += i;
if ((dropDSM & DEV_SATA) != 0) {
Size = get_size(dsdt, k);
sizeoffset = - 1 - Size;
len = move_data(k - 1, dsdt, len, sizeoffset);
len = CorrectOuters(dsdt, len, k - 2, sizeoffset);
DBG("_DSM in SATA already exists, dropped\n");
} else {
DBG("_DSM already exists, patch SATA will not be applied\n");
return len;
}
}
}
DBG("Start SATA Fix\n");
root = aml_create_node(NULL);
// add Method(_DSM,4,NotSerialized)
if (gSettings.FakeSATA || !gSettings.NoDefaultProperties) {
met = aml_add_method(root, "_DSM", 4);
met2 = aml_add_store(met);
pack = aml_add_package(met2);
if (gSettings.FakeSATA) {
aml_add_string(pack, "device-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeID, 4);
aml_add_string(pack, "vendor-id");
aml_add_byte_buffer(pack, (CHAR8*)&FakeVen, 4);
}
if (!CustProperties(pack, DEV_SATA) &&
!gSettings.NoDefaultProperties &&
!gSettings.FakeSATA) {
aml_add_string(pack, "empty");
aml_add_byte(pack, 0);
}
aml_add_local0(met2);
aml_add_buffer(met, dtgp_1, sizeof(dtgp_1));
}
// finish Method(_DSM,4,NotSerialized)
aml_calculate_size(root);
sata = AllocateZeroPool(root->Size);
sizeoffset = root->Size;
aml_write_node(root, sata, 0);
aml_destroy_node(root);
// move data to back for add DSM
BridgeSize = get_size(dsdt, SATAADR);
i = SATAADR + BridgeSize;
len = move_data(i, dsdt, len, sizeoffset);
CopyMem(dsdt + i, sata, sizeoffset);
// Fix Device SATA size
k = write_size(SATAADR, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, SATAADR-3, sizeoffset);
FreePool(sata);
return len;
}
/*
UINT32 FIXCPU1 (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j;
UINT32 count=0;
UINT32 pradr=0;
UINT32 prsize=0, size=0;
UINT32 prsize1=0;
INT32 offset, sizeoffset;
DBG("Start CPUS=1 Fix\n");
DBG("len = 0x%08x\n", len);
// find _PR_ and get PR size
for (i=0x20; i<len-4; i++) {
if (dsdt[i] == '_' && dsdt[i+1] == 'P' && dsdt[i+2] == 'R' && dsdt[i+3] == '_') {
DBG("Found _PR_\n");
for (j=0; j<10; j++) {
if (dsdt[i-j] == 0x10) {
prsize = get_size(dsdt, i-j+1);
if(!prsize) continue;
prsize1 = prsize;
pradr = i-j+1;
// size > 0x3F there should be had P_states code so don't fix
if (prsize > 0x3F) return len;
DBG("_PR_ adr = 0x%08x size = 0x%08x\n", pradr, prsize);
break;
}
}
break;
}
}
sizeoffset = 9;
// find alias
for (i=pradr; i<prsize1; i++) {
if (dsdt[i] == 0x5B && dsdt[i+1] == 0x83) {
size = get_size(dsdt, i+2);
DBG("OP size = 0x%08x\n", size);
// if OP name not CPUX.... need add alias in OP back
offset = i + 3 + (dsdt[i+2] >> 6);
if (dsdt[offset] == '\\') offset = i + 8 + (dsdt[i+7] >> 6);
if (dsdt[i+2+size] != 0x06 && dsdt[offset] != 'C' && dsdt[offset+1] != 'P' && dsdt[offset+2] != 'U') {
DBG("Found alias CPU.\n");
len = move_data(i+2+size, dsdt, len, sizeoffset);
dsdt[i+2+size] = 0x06;
dsdt[i+3+size] = dsdt[i+2];
dsdt[i+4+size] = dsdt[i+3];
dsdt[i+5+size] = dsdt[i+4];
dsdt[i+6+size] = dsdt[i+5];
dsdt[i+7+size] = 'C';
dsdt[i+8+size] = 'P';
dsdt[i+9+size] = 'U';
dsdt[i+10+size] = dsdt[i+5];
j = write_size(pradr, dsdt, len, sizeoffset);
sizeoffset += j;
len += j;
count++;
continue;
}
}
}
DBG("return len=%x\n", len);
return len;
}
*/
UINT32 FIXWAK (UINT8 *dsdt, UINT32 len, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE* fadt)
{
UINT32 i, j, k;
UINT32 wakadr=0;
UINT32 waksize=0;
UINT32 sizeoffset = 0, sizeoffset2 = 0;
// UINT16 PM30 = 0x430; //default
BOOLEAN ReturnFound = FALSE;
DBG("Start _WAK Return Fix\n");
for (i = 0x24; len >= 5 && i < len - 5; i++) {
if(dsdt[i] == '_' && dsdt[i+1] == 'W' && dsdt[i+2] == 'A' && dsdt[i+3] == 'K') {
for (j=0; j<10; j++) {
if(dsdt[i-j] == 0x14) { //Method _WAK found
wakadr = i-j+1;
waksize = get_size(dsdt, wakadr);
if (!waksize) {
continue;
}
//DBG( "_WAK adr = 0x%08x, size = 0x%08x\n", wakadr, waksize);
for (k=0; k<waksize; k++) {
if (dsdt[i+k] == 0xA4) { // Return
DBG( "_WAK Method find return data, don't need to patch.\n");
// return len;
ReturnFound = TRUE;
}
}
//Slice - this patch disabled as useless
/* if (gSettings.SlpWak) {
DBG(" add SLP_SMI_EN=0 into _WAK\n");
PM30 = (UINT16)fadt->Pm1aEvtBlk + 0x30;
sizeoffset = sizeof(wakslp1) + 3 + sizeof(wakslp2);
len = move_data(i + 5, dsdt, len, sizeoffset);
CopyMem(dsdt + i + 5, wakslp1, sizeof(wakslp1));
k = i + 5 + sizeof(wakslp1);
dsdt[k++] = 0x0B;
dsdt[k++] = PM30 & 0xFF;
dsdt[k++] = PM30 >> 8;
CopyMem(dsdt + k, wakslp2, sizeof(wakslp2));
k = write_size(wakadr, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
} */
sizeoffset = sizeof(waksecur);
len = move_data(i + 5, dsdt, len, sizeoffset);
CopyMem(dsdt + i + 5, waksecur, sizeof(waksecur));
k = write_size(wakadr, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
if (!ReturnFound) {
DBG( "_WAK Method need return data, will patch it.\n");
waksize = get_size(dsdt, wakadr);
if (!waksize) {
continue;
}
sizeoffset2 = sizeof(wakret);
len = move_data(wakadr + waksize, dsdt, len, sizeoffset2);
CopyMem(dsdt + wakadr + waksize, wakret, sizeoffset2);
k = write_size(wakadr, dsdt, len, sizeoffset2);
sizeoffset += k + sizeoffset2;
len += k;
}
len = CorrectOuters(dsdt, len, wakadr-2, sizeoffset);
break;
}
}
break;
}
}
DBG("return len=%x\n", len);
return len;
}
#if 0
UINT32 FIXGPE (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j, k, l, m, n;
UINT32 gpeadr=0;
// UINT32 gpesize=0;
UINT32 pwrbadr=0;
UINT32 pwrbsize=0;
UINT32 usbcount=0;
UINT32 PWRBADR = 0;
// UINT32 adr=0;
INT32 offset=0;
INT32 sizeoffset;
// BOOLEAN pwrbfix = FALSE;
// BOOLEAN usbpwrb = FALSE;
// BOOLEAN foundpwrb = FALSE;
sizeoffset = sizeof(pwrb);
if (!PWRBADR) {
return len;
}
DBG("Start _GPE device remove error Fix\n");
//DBG("len = 0x%08x\n", len);
for (i=0; i<len-10; i++)
{ //what kind of nonsense here!
if(dsdt[i] == '_' && dsdt[i+1] == 'L' && (dsdt[i-2] == 0x14 || dsdt[i-3] == 0x14 || dsdt[i-4] == 0x14 || dsdt[i-5] == 0x14)) {
for (j=0; j<10; j++) {
if(dsdt[i-j] == 0x14) {
pwrbsize = get_size(dsdt, i-j+1);
pwrbadr = i-j+1;
//DBG( "_LXX adr = 0x%08x, size = 0x%08x\n", pwrbadr, pwrbsize);
for (k=pwrbadr; k<pwrbadr+pwrbsize; k++) {
for (l=0; l<usb; l++) { // find USB _LXX
if (dsdt[k] == UsbName[l][0] && dsdt[k+1] == UsbName[l][1] &&
dsdt[k+2] == UsbName[l][2] && dsdt[k+3] == UsbName[l][3]) {
//DBG( "found USB _GPE Method.\n");
// usbpwrb = TRUE;
if (!usbcount) {
//DBG( "will to find Scope(\\_GPE).\n");
for (m=0; m<300; m++) {
if (dsdt[i-m] == 'E' && dsdt[i-m-1] == 'P' && dsdt[i-m-2] == 'G' && dsdt[i-m-3] == '_') {
for (n=0; n<15; n++) {
if (dsdt[i-m-n] == 0x10) {
gpeadr = i-m-n+1;
// gpesize = get_size(dsdt, i-m-n+1);
//DBG( "_GPE adr = 0x%08x, size = 0x%08x\n", gpeadr, gpesize);
break;
}
}
break;
}
}
}
break;
}
}
}
}
}
}
}
if (usbcount) {
sizeoffset = offset;
k = write_size(gpeadr, dsdt, len, sizeoffset);
sizeoffset += k;
len += k;
len = CorrectOuters(dsdt, len, gpeadr-3, sizeoffset);
}
return len;
}
#endif
#if 0
UINT32 FIXPWRB (UINT8* dsdt, UINT32 len)
{
UINT32 i, j=0;
UINT32 adr=0, hid=0, size = 0;
CHAR8 Name[4];
INT32 sizeoffset;
//search PWRB PNP0C0C
for (i=0x20; i<len-6; i++) {
if (CmpPNP(dsdt, i, 0x0C0C)) {
adr = devFind(dsdt, i);
if (!adr) {
continue;
}
size = get_size(dsdt, adr);
if(size){
hid = i + 10; //the place after HID PNP0C0C
break;
}
}
}
if (size) {
//check name and replace
if (size < 0x40) {
j = adr + 1;
} else {
j = adr + 2;
}
for (i=0; i<4; i++) {
Name[i] = dsdt[j+i];
}
ReplaceName(dsdt, len, Name, "PWRB");
sizeoffset = sizeof(pwrbprw);
len = move_data(hid, dsdt, len, sizeoffset);
CopyMem(dsdt+hid, pwrbprw, sizeoffset);
i = write_size(adr, dsdt, len, sizeoffset);
sizeoffset += i;
len += i;
len = CorrectOuters(dsdt, len, adr-3, sizeoffset);
}
return len;
}
#endif
UINT32 FIXSHUTDOWN_ASUS (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j, sizeoffset = 0;
UINT32 adr, adr1 = 0, adr2, size, shift = 0;
CHAR8 *shutdown = NULL;
DBG("Start SHUTDOWN Fix len=%x\n", len);
adr = FindMethod(dsdt, len, "_PTS");
if (!adr) {
MsgLog("no _PTS???\n");
return len;
}
if (gSettings.SuspendOverride) {
shutdown = &shutdown1[0];
sizeoffset = sizeof(shutdown1);
} else {
shutdown = &shutdown0[0];
sizeoffset = sizeof(shutdown0);
}
/*
adr \ _ P T S insert offset
14 16 5C 5F 50 54 53 01 < A0 05 93 68 0A 05 A1 08 >
body
53 4D 49 5F 0A 8A 68
*/
// sizeoffset = sizeof(shutdown); // == 18
size = get_size(dsdt, adr);
adr1 = adr;
for (j=0; j<20; j++) {
if ((dsdt[adr+j] == 'T') && (dsdt[adr+j+1] == 'S')) {
adr1 = adr+j+3; //address of body
break;
}
}
adr2 = adr1 + sizeoffset - 1; //jump adr
len = move_data(adr1, dsdt, len, sizeoffset); //new len
CopyMem(dsdt+adr1, shutdown, sizeoffset); //insert shutdown
i = adr + size - adr1; //body size
shift = write_offset(adr2, dsdt, len, i); //may return 0 or 1
len += shift;
sizeoffset += shift;
shift = write_size(adr, dsdt, len, sizeoffset);
// sizeoffset += shift;
len += shift;
return len;
}
#if 0
//Slice - this procedure was not corrected and mostly wrong
UINT32 FIXOTHER (UINT8 *dsdt, UINT32 len)
{
UINT32 i, j, k, m, offset, l;
UINT32 size;
// Fix USB _PRW value for 0x0X, 0x04 ==> 0x0X, 0x01
for(j=0; j<usb; j++) {
for (i=0; i<len-5; i++) {
if (CmpAdr(dsdt, i, USBADR[j])) {
// get USB name
UsbName[j] = AllocateZeroPool(5);
CopyMem(UsbName[j], dsdt+i, 4);
DBG("found USB device NAME(_ADR,0x%08x) And Name is %a\n",
USBADR[j], UsbName[j]);
k = (i+1);
while (k < (i+200)) {
if (dsdt[k] == 0x14 && dsdt[k+2] == '_' && dsdt[k+3] == 'P' && dsdt[k+4] == 'R' && dsdt[k+5] == 'W') {
offset = k;
m = dsdt[k+1];
if (dsdt[offset+m] != 0x03) {
if (dsdt[offset+m] == 0x01)
dsdt[offset+m] = 0x03;
if (dsdt[offset+m] == 0x04)
dsdt[offset+m] = 0x01;
//DBG("found USB Method(_PRW) and will patch fix\n");
}
break;
}
k = (i+1);
while (k < (i+200)) {
if (dsdt[k] == 0x14 && dsdt[k+2] == '_' && dsdt[k+3] == 'S' && dsdt[k+4] == '3' && dsdt[k+5] == 'D') {
size = dsdt[k+1];
for (l=0; l<size; l++) {
if (dsdt[k+1+l] == 0xA4 && dsdt[k+2+l] == 0x0A && dsdt[k+3+l] != 0x03) {
dsdt[k+3+l] = 0x03;
}
}
break;
}
k++;
}
k++;
}
/*
for (k=(i+1); k<(i+200); k++) {
if (dsdt[k] == 0x14 && dsdt[k+2] == '_' && dsdt[k+3] == 'P' && dsdt[k+4] == 'R' && dsdt[k+5] == 'W') {
offset = k;
m = dsdt[k+1];
if (dsdt[offset+m] != 0x03) {
if (dsdt[offset+m] == 0x01)
dsdt[offset+m] = 0x03;
if (dsdt[offset+m] == 0x04)
dsdt[offset+m] = 0x01;
//DBG("found USB Method(_PRW) and will patch fix\n");
}
break;
}
for (k=i+1; k<i+200; k++) {
if (dsdt[k] == 0x14 && dsdt[k+2] == '_' && dsdt[k+3] == 'S' && dsdt[k+4] == '3' && dsdt[k+5] == 'D') {
size = dsdt[k+1];
for (l=0; l<size; l++) {
if (dsdt[k+1+l] == 0xA4 && dsdt[k+2+l] == 0x0A && dsdt[k+3+l] != 0x03) {
dsdt[k+3+l] = 0x03;
}
}
break;
}
}
//for (k=i+1; k<i+200; k++) {
// if (dsdt[k] == 0x14 && dsdt[k+2] == '_' && dsdt[k+3] == 'P' && dsdt[k+4] == 'S' && dsdt[k+5] == 'W')
// {
// size = dsdt[k+1];
// for (l=0; l<size; l++)
// {
// if (dsdt[k+1+l] == 0x70 && dsdt[k+2+l] == 0x00)
// {
// dsdt[k+2+l] = 0x03;
// }
// }
// break;
// }
//}
break;
}
*/
}
}
}
for (j=0; j<usb; j++){
FreePool(UsbName[j]);
}
// fix _T_0 _T_1 _T_2 _T_3
for (i=0; i<len-10; i++) {
if (dsdt[i] == '_' && dsdt[i+1] == 'T' && dsdt[i+2] == '_' &&
(dsdt[i+3] == '0' || dsdt[i+3] == '1' || dsdt[i+3] == '2' || dsdt[i+3] == '3')) {
dsdt[i] = dsdt[i+1];
dsdt[i+1] = dsdt[i+2];
dsdt[i+2] = dsdt[i+3];
dsdt[i+3] = '_';
}
}
// fix MUTE Possible operator timeout is ignored
for (i=0; i<len-10; i++) {
if (dsdt[i] == 0x5B && dsdt[i+1] == 0x23 && dsdt[i+2] == 0x4D &&
dsdt[i+3] == 0x55 && dsdt[i+4] == 0x54 && dsdt[i+5] == 0x45) {
dsdt[i+6] = 0xFF;
dsdt[i+7] = 0xFF;
}
}
return len;
}
#endif
VOID FixRegions (UINT8 *dsdt, UINT32 len)
{
UINTN i, j;
INTN shift;
CHAR8 Name[8];
CHAR8 NameAdr[8];
OPER_REGION *p;
// BOOLEAN Corrected = FALSE;
// OperationRegion (GNVS, SystemMemory, 0xDE2E9E18, 0x01CD)
// 5B 80 47 4E 56 53 00 0C 18 9E 2E DE 0B CD 01
//or
// Name (RAMB, 0xDD991188)
// OperationRegion (\RAMW, SystemMemory, RAMB, 0x00010000)
// 08 52 41 4D 42 0C 88 11 99 DD
// 5B 80 52 41 4D 57 00 52 41 4D 42 0C 00 00 01 00
if (!gRegions) {
return;
}
for (i = 0x20; len >= 15 && i < len - 15; i++) {
if ((dsdt[i] == 0x5B) && (dsdt[i+1] == 0x80) && GetName(dsdt, (INT32)(i+2), &Name[0], &shift)) {
//this is region. Compare to bios tables
p = gRegions;
while (p) {
if (AsciiStrStr(p->Name, Name)) {
UINT32 oldAddress = 0;
//apply patch
if (dsdt[i+7+shift] == 0x0C) {
CopyMem(&oldAddress, &dsdt[i+8+shift], 4);
CopyMem(&dsdt[i+8+shift], &p->Address, 4);
} else if (dsdt[i+7+shift] == 0x0B) {
CopyMem(&oldAddress, &dsdt[i+8+shift], 2);
CopyMem(&dsdt[i+8+shift], &p->Address, 2);
} else {
//propose this is indirect name
if (GetName(dsdt, (INT32)(i+7+shift), &NameAdr[0], NULL)) {
j = FindName(dsdt, len, &NameAdr[0]);
if (j > 0) {
MsgLog(" indirect name=%a\n", NameAdr);
if (dsdt[j+4] == 0x0C) {
CopyMem(&oldAddress, &dsdt[j+5], 4);
CopyMem(&dsdt[j+5], &p->Address, 4);
// Corrected = TRUE;
} else if (dsdt[j+4] == 0x0B) {
CopyMem(&oldAddress, &dsdt[j+5], 2);
CopyMem(&dsdt[j+5], &p->Address, 2);
} else {
MsgLog("... value not defined\n");
}
}
}
}
if (oldAddress != p->Address) {
MsgLog("OperationRegion (%a...) corrected from 0x%x to addr=0x%x\n", Name, oldAddress, p->Address);
}
break;
}
p = p->next;
}
}
}
}
VOID GetBiosRegions(UINT8 *buffer)
{
EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
// UINT8 *buffer = NULL;
UINT32 bufferLen = 0;
UINTN i, j;
INTN shift, shift2;
CHAR8 Name[8];
CHAR8 NameAdr[8];
if (!buffer) {
return;
}
// gRegions = NULL;
// buffer = (UINT8*)(UINTN)fadt->Dsdt;
TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*)buffer;
bufferLen = TableHeader->Length;
for (i=0x24; bufferLen >= 15 && i < bufferLen - 15; i++) {
if ((buffer[i] == 0x5B) && (buffer[i+1] == 0x80) &&
GetName(buffer, (INT32)(i+2), &Name[0], &shift)) {
if (buffer[i+6+shift] == 0) {
//this is SystemMemory region. Write to bios regions tables
OPER_REGION tmp;
tmp.Address = 0;
CopyMem(&tmp.Name[0], &buffer[i+2+shift], 4);
tmp.Name[4] = 0;
if (buffer[i+7+shift] == 0x0C) {
CopyMem(&tmp.Address, &buffer[i+8+shift], 4);
} else if (buffer[i+7+shift] == 0x0B) {
CopyMem(&tmp.Address, &buffer[i+8+shift], 2);
} else if (GetName(buffer, (INT32)(i+7+shift), &NameAdr[0], &shift2)) {
j = FindName(buffer, bufferLen, &NameAdr[0]);
if (j > 0) {
if (buffer[j+4] == 0x0C) {
CopyMem(&tmp.Address, &buffer[j+5], 4);
} else if (buffer[j+4] == 0x0B) {
CopyMem(&tmp.Address, &buffer[j+5], 2);
}
}
}
if (tmp.Address) {
OPER_REGION *newRegion = AllocateZeroPool(sizeof(OPER_REGION));
MsgLog("Found OperationRegion(%a, SystemMemory, %x, ...)\n", tmp.Name, tmp.Address);
*newRegion = tmp;
newRegion->next = gRegions;
gRegions = newRegion;
} else {
// ignore OperationRegion where the address cannot be determined
//DBG("Unable to determine address for OperationRegion(%a, SystemMemory, ...) skipping\n", tmp.Name);
}
}
}
}
}
// RehabMan: Fix Mutex with non-zero SyncLevel (change to zero)
// For example: Mutex(ECMX, 3) -> Mutex(ECMX, 0)
// representation example:
// Mutex(M2, 1) -> 5B 01 4D 32 5F 5F 01
// Although Mutex with non-zero SyncLevel is perfectly legal macOS/OS X doesn't like
// One of the common fixes for ACPI battery status on laptops
#define IsNameChar(ch) (((ch)>='A' && (ch)<='Z') || ((ch)>='0' && (ch)<='9') || (ch)=='_')
VOID FixMutex(UINT8 *dsdt, UINT32 len)
{
UINT8* p = dsdt + sizeof(EFI_ACPI_DESCRIPTION_HEADER);
UINT8* end = dsdt + len - 7; // pattern is 7-bytes
MsgLog("Start Mutex Fix\n");
for (; p <= end; p++) {
if (p[0] == 0x5b && p[1] == 0x01 &&
IsNameChar(p[2]) && IsNameChar(p[3]) && IsNameChar(p[4]) && IsNameChar(p[5])) {
if (p[6] != 0) {
MsgLog("Fixing Mutex(%c%c%c%c, %d)\n", p[2], p[3], p[4], p[5], p[6]);
}
p[6] = 0;
}
}
}
/*
_SB.PCI0.RP02.PSXS
We have to take into account fields like
Scope(\_SB)
{
Device (PCI0)
{
Device(RP02)
{
Device(PSXS) <- to patch
{
Method(_ON)
{
}
Method(_OFF)
{
}
}
PSXS._ON() <- to patch
}
Scope(RP02)
{
PSXS._OFF() <- to patch
}
Device(RP03)
{
Device(PSXS) <- to not patch
{
}
PSXS._ON() <- to not patch
}
*/
BOOLEAN isACPI_Char(CHAR8 C)
{
return (((C >= 'A') && (C <= 'Z')) ||
((C >= '0') && (C <= '9')) ||
(C == '_'));
}
BOOLEAN CmpFullName(UINT8* Table, UINTN Len, ACPI_NAME_LIST *Bridge)
{
// "RP02" NameLen=4
// "_SB_PCI0RP02" NameLen=12
UINTN NameLen = 0;
INTN i = 0;
CHAR8 *Name;
while ((NameLen < Len) && isACPI_Char((CHAR8)Table[NameLen])) NameLen++;
NameLen &= ~3;
if (NameLen < 4) {
return FALSE;
}
Name = AllocateCopyPool(NameLen + 1, Table);
Name[NameLen] = '\0';
i = NameLen - 4;
while (Bridge && (i >= 0)) {
if (AsciiStrStr(Name + i, Bridge->Name) == NULL) { //compare Bridge->Name with RP02, Next->Name with PCI0 then _SB_
FreePool(Name);
return FALSE;
}
i -= 4;
Bridge = Bridge->Next;
}
FreePool(Name);
return TRUE;
}
VOID RenameDevices(UINT8* table)
{
ACPI_NAME_LIST *List;
ACPI_NAME_LIST *Bridge;
CHAR8 *Replace;
CHAR8 *Find;
INTN i, k;
UINTN index;
INTN size;
UINTN len = ((EFI_ACPI_DESCRIPTION_HEADER*)table)->Length;
INTN adr, shift, Num = 0;
BOOLEAN found;
for (index = 0; index < gSettings.DeviceRenameCount; index++) {
List = gSettings.DeviceRename[index].Next;
Replace = gSettings.DeviceRename[index].Name;
Find = List->Name;
Bridge = List->Next;
MsgLog("Name: %a, Bridge: %a, Replace: %a\n", Find, Bridge->Name, Replace);
adr = 0;
do
{
shift = FindBin(table + adr, (UINT32)(len - adr), (UINT8*)Find, 4); //next occurence
if (shift < 0) {
break; //not found
}
adr += shift;
// DBG("found Name @ 0x%x\n", adr);
if (!Bridge || (FindBin(table + adr - 4, 5, (UINT8*)(Bridge->Name), 4) == 0)) { // long name like "RP02.PXSX"
CopyMem(table + adr, Replace, 4);
adr += 5; //at least, it is impossible to see PXSXPXSX
// DBG("replaced\n");
Num++;
continue;
}
//find outer device or scope
i = adr;
while ((i > 0) && isACPI_Char(table[i])) i--; //skip attached name
i -= 6; //skip size and device field
// DBG("search for bridge since %d\n", adr);
while (i > 0x20) { //find devices that previous to adr
found = FALSE;
//check device
if ((table[i] == 0x5B) && (table[i + 1] == 0x82) && !CmpNum(table, (INT32)i, TRUE)) { //device candidate
k = i + 2;
found = TRUE;
}
//check scope
if ((table[i] == 0x10) && !CmpNum(table, (INT32)i, TRUE)) {
k = i + 1;
found = TRUE;
}
if (found) { // i points to Device or Scope
size = get_size(table, (UINT32)(UINTN)k); //k points to size // DBG("found bridge candidate 0x%x size %d\n", table[i], size);
if (size) {
if ((k + size) > (adr + 4)) { //Yes - it is outer
// DBG("found Bridge device begin=%x end=%x\n", k, k+size);
if (table[k] < 0x40) {
k += 1;
}
else if ((table[k] & 0x40) != 0) {
k += 2;
}
else if ((table[k] & 0x80) != 0) {
k += 3;
} //now k points to the outer name
if (CmpFullName(table + k, len - k, Bridge)) {
CopyMem(table + adr, Replace, 4);
adr += 5;
DBG("found Bridge device begin=%x end=%x\n", k, k+size);
// DBG(" name copied\n");
Num++;
break; //cancel search outer bridge, we found it.
}
} //else not an outer device
} //else wrong size field - not a device
} //else not a device or scope
i--;
} //while find outer bridge
adr += 5;
} while (1); //next occurence
} //DeviceRenameCount
MsgLog(" %d replacements\n", Num);
}
VOID FixBiosDsdt (UINT8* temp, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE* fadt, CHAR8 *OSVersion)
{
UINT32 DsdtLen;
UINTN i;
if (!temp) {
return;
}
//Reenter requires ZERO values
HDAFIX = TRUE;
GFXHDAFIX = TRUE;
USBIDFIX = TRUE;
DsdtLen = ((EFI_ACPI_DESCRIPTION_HEADER*)temp)->Length;
if ((DsdtLen < 20) || (DsdtLen > 400000)) { //fool proof (some ASUS dsdt > 300kb?)
MsgLog("DSDT length out of range\n");
return;
}
// DBG("========= Auto patch DSDT Starting ========\n");
DbgHeader("FixBiosDsdt");
// First check hardware address: GetPciADR(DevicePath, &NetworkADR1, &NetworkADR2);
CheckHardware();
//arbitrary fixes
if (gSettings.PatchDsdtNum > 0) {
MsgLog("Patching DSDT:\n");
for (i = 0; i < gSettings.PatchDsdtNum; i++) {
if (!gSettings.PatchDsdtFind[i] || !gSettings.LenToFind[i]) {
continue;
}
MsgLog(" - [%a]:", gSettings.PatchDsdtLabel[i]); //yyyy
if (gSettings.PatchDsdtMenuItem[i].BValue) {
if (!gSettings.PatchDsdtTgt[i]) {
DsdtLen = FixAny(temp, DsdtLen,
gSettings.PatchDsdtFind[i], gSettings.LenToFind[i],
gSettings.PatchDsdtReplace[i], gSettings.LenToReplace[i]);
}else{
// DBG("Patching: renaming in bridge\n");
DsdtLen = FixRenameByBridge2(temp, DsdtLen,
gSettings.PatchDsdtTgt[i],
gSettings.PatchDsdtFind[i],
gSettings.LenToFind[i],
gSettings.PatchDsdtReplace[i],
gSettings.LenToReplace[i]);
}
} else {
MsgLog(" disabled\n");
}
}
}
//renaming Devices
RenameDevices(temp);
// find ACPI CPU name and hardware address
findCPU(temp, DsdtLen);
// add Method (DTGP, 5, NotSerialized)
if ((gSettings.FixDsdt & FIX_DTGP)) {
if (!FindMethod(temp, DsdtLen, "DTGP")) {
CopyMem((CHAR8 *)temp+DsdtLen, dtgp, sizeof(dtgp));
DsdtLen += sizeof(dtgp);
((EFI_ACPI_DESCRIPTION_HEADER*)temp)->Length = DsdtLen;
}
}
// gSettings.PCIRootUID = 0;
findPciRoot(temp, DsdtLen);
// Fix RTC
if ((gSettings.FixDsdt & FIX_RTC)) {
// DBG("patch RTC in DSDT \n");
DsdtLen = FixRTC(temp, DsdtLen);
}
// Fix TMR
if ((gSettings.FixDsdt & FIX_TMR)) {
// DBG("patch TMR in DSDT \n");
DsdtLen = FixTMR(temp, DsdtLen);
}
// Fix PIC or IPIC
if ((gSettings.FixDsdt & FIX_IPIC) != 0) {
// DBG("patch IPIC in DSDT \n");
DsdtLen = FixPIC(temp, DsdtLen);
}
// Fix HPET
if ((gSettings.FixDsdt & FIX_HPET) != 0) {
// DBG("patch HPET in DSDT \n");
DsdtLen = FixHPET(temp, DsdtLen);
}
// Fix LPC if don't had HPET don't need to inject LPC??
if (LPCBFIX && (gCPUStructure.Family == 0x06) && (gSettings.FixDsdt & FIX_LPC)) {
// DBG("patch LPC in DSDT \n");
DsdtLen = FIXLPCB(temp, DsdtLen);
}
// Fix Display
if ((gSettings.FixDsdt & FIX_DISPLAY) || (gSettings.FixDsdt & FIX_INTELGFX)) {
INT32 j;
for (j=0; j<4; ++j) {
if (DisplayADR1[j]) {
if (((DisplayVendor[j] != 0x8086) && (gSettings.FixDsdt & FIX_DISPLAY)) ||
((DisplayVendor[j] == 0x8086) && (gSettings.FixDsdt & FIX_INTELGFX))) {
DsdtLen = FIXDisplay(temp, DsdtLen, j);
MsgLog("patch Display #%d of Vendor=0x%4x\n", j, DisplayVendor[j]);
}
}
}
}
// Fix Network
if ((gSettings.FixDsdt & FIX_LAN)) {
// DBG("patch LAN in DSDT \n");
UINT32 j;
for (j = 0; j <= net_count; ++j) {
if (NetworkADR1[j]) {
MsgLog("patch LAN0 in DSDT \n");
DsdtLen = FIXNetwork(temp, DsdtLen, j);
}
}
}
// Fix Airport
if (ArptADR1 && (gSettings.FixDsdt & FIX_WIFI)) {
// DBG("patch Airport in DSDT \n");
DsdtLen = FIXAirport(temp, DsdtLen);
}
// Fix SBUS
if (SBUSADR1 && (gSettings.FixDsdt & FIX_SBUS)) {
// DBG("patch SBUS in DSDT \n");
DsdtLen = FIXSBUS(temp, DsdtLen);
}
// Fix IDE inject
if (IDEFIX && (IDEVENDOR == 0x8086 || IDEVENDOR == 0x11ab) && (gSettings.FixDsdt & FIX_IDE)) {
// DBG("patch IDE in DSDT \n");
DsdtLen = FIXIDE(temp, DsdtLen);
}
// Fix SATA AHCI orange icon
if (SATAAHCIADR1 && (SATAAHCIVENDOR == 0x8086) && (gSettings.FixDsdt & FIX_SATA)) {
DBG("patch AHCI in DSDT \n");
DsdtLen = FIXSATAAHCI(temp, DsdtLen);
}
// Fix SATA inject
if (SATAFIX && (SATAVENDOR == 0x8086) && (gSettings.FixDsdt & FIX_SATA)) {
DBG("patch SATA in DSDT \n");
DsdtLen = FIXSATA(temp, DsdtLen);
}
// Fix Firewire
if (FirewireADR1 && (gSettings.FixDsdt & FIX_FIREWIRE)) {
DBG("patch FRWR in DSDT \n");
DsdtLen = FIXFirewire(temp, DsdtLen);
}
// HDA HDEF
if (HDAFIX && (gSettings.FixDsdt & FIX_HDA)) {
DBG("patch HDEF in DSDT \n");
DsdtLen = AddHDEF(temp, DsdtLen, OSVersion);
}
//Always add MCHC for PM
if ((gCPUStructure.Family == 0x06) && (gSettings.FixDsdt & FIX_MCHC)) {
// DBG("patch MCHC in DSDT \n");
DsdtLen = AddMCHC(temp, DsdtLen);
}
//add IMEI
if ((gSettings.FixDsdt & FIX_IMEI)) {
DsdtLen = AddIMEI(temp, DsdtLen);
}
//Add HDMI device
if ((gSettings.FixDsdt & FIX_HDMI)) {
DsdtLen = AddHDMI(temp, DsdtLen);
}
// Always Fix USB
if ((gSettings.FixDsdt & FIX_USB)) {
DsdtLen = FIXUSB(temp, DsdtLen);
}
if ((gSettings.FixDsdt & FIX_WAK)){
// Always Fix _WAK Return value
DsdtLen = FIXWAK(temp, DsdtLen, fadt);
}
// DBG("patch warnings \n");
// Always Fix alias cpu FIX cpus=1
// DsdtLen = FIXCPU1(temp, DsdtLen);
// DsdtLen = FIXPWRB(temp, DsdtLen);
// USB Device remove error Fix
// DsdtLen = FIXGPE(temp, DsdtLen);
if ((gSettings.FixDsdt & FIX_UNUSED)) {
//I want these fixes even if no Display fix. We have GraphicsInjector
DsdtLen = DeleteDevice("CRT_", temp, DsdtLen);
DsdtLen = DeleteDevice("DVI_", temp, DsdtLen);
//good company
DsdtLen = DeleteDevice("SPKR", temp, DsdtLen);
DsdtLen = DeleteDevice("ECP_", temp, DsdtLen);
DsdtLen = DeleteDevice("LPT_", temp, DsdtLen);
DsdtLen = DeleteDevice("FDC0", temp, DsdtLen);
DsdtLen = DeleteDevice("ECP1", temp, DsdtLen);
DsdtLen = DeleteDevice("LPT1", temp, DsdtLen);
}
if ((gSettings.FixDsdt & FIX_ACST)) {
ReplaceName(temp, DsdtLen, "ACST", "OCST");
ReplaceName(temp, DsdtLen, "ACSS", "OCSS");
ReplaceName(temp, DsdtLen, "APSS", "OPSS");
ReplaceName(temp, DsdtLen, "APSN", "OPSN");
ReplaceName(temp, DsdtLen, "APLF", "OPLF");
}
if ((gSettings.FixDsdt & FIX_PNLF)) {
DsdtLen = AddPNLF(temp, DsdtLen);
}
if ((gSettings.FixDsdt & FIX_S3D)) {
FixS3D(temp, DsdtLen);
}
//Fix OperationRegions
if ((gSettings.FixDsdt & FIX_REGIONS)) {
FixRegions(temp, DsdtLen);
}
//RehabMan: Fix Mutex objects
if ((gSettings.FixDsdt & FIX_MUTEX)) {
FixMutex(temp, DsdtLen);
}
// pwrb add _CID sleep button fix
if ((gSettings.FixDsdt & FIX_ADP1)) {
DsdtLen = FixADP1(temp, DsdtLen);
}
// other compiler warning fix _T_X, MUTE .... USB _PRW value form 0x04 => 0x01
// DsdtLen = FIXOTHER(temp, DsdtLen);
if ((gSettings.FixDsdt & FIX_WARNING) || (gSettings.FixDsdt & FIX_DARWIN)) {
if (!FindMethod(temp, DsdtLen, "GET9") &&
!FindMethod(temp, DsdtLen, "STR9") &&
!FindMethod(temp, DsdtLen, "OOSI")) {
DsdtLen = FIXDarwin(temp, DsdtLen);
}
}
// Fix SHUTDOWN For ASUS
if ((gSettings.FixDsdt & FIX_SHUTDOWN)) {
DsdtLen = FIXSHUTDOWN_ASUS(temp, DsdtLen); //safe to do twice
}
// Finish DSDT patch and resize DSDT Length
/*
temp[4] = (DsdtLen & 0x000000FF);
temp[5] = (UINT8)((DsdtLen & 0x0000FF00) >> 8);
temp[6] = (UINT8)((DsdtLen & 0x00FF0000) >> 16);
temp[7] = (UINT8)((DsdtLen & 0xFF000000) >> 24);
CopyMem((UINT8*)((EFI_ACPI_DESCRIPTION_HEADER*)temp)->OemId, (UINT8*)BiosVendor, 6);
//DBG("orgBiosDsdtLen = 0x%08x\n", orgBiosDsdtLen);
((EFI_ACPI_DESCRIPTION_HEADER*)temp)->Checksum = 0;
((EFI_ACPI_DESCRIPTION_HEADER*)temp)->Checksum = (UINT8)(256-Checksum8(temp, DsdtLen));
*/
EFI_ACPI_DESCRIPTION_HEADER* Table = (EFI_ACPI_DESCRIPTION_HEADER*)temp;
Table->Length = DsdtLen;
FixChecksum(Table);
//DBG("========= Auto patch DSDT Finished ========\n");
//PauseForKey(L"waiting for key press...\n");
}