Chameleon Rc5 Mode With Mem Detection Enabled And Automatic P-states & C-states Generation For Native Power Managment |
|
|

Jul 20 2010, 09:26 AM


- Member
- Group: Developer
- Posts: 66
If you experienced a problem patching your DSDT/SSDT to enable Mac OS X native power management, or you don't know how to do this - the new bootloader is for you! Should work on most modern systems/processors.
Bootloader based on latest Chameleon RC5 rev184. Mem detection is enabled and slightly modified: fixed system profiler returns error while reading memory info in some cases. P-States & C-States are exported to the system via additional SSDTs, so if you have native SSDTs with _CST methods you should use "DropSSDT" = "Yes" option in boot.plist. If you have modded DSDT with _CST methods you should remove them or it'll be kernel panic on system start. The bootloader also supports multiple SSDT loading (names should be SSDT.aml, SSDT-1.aml ... SSDT-29.aml). Bootloader also supports latest graphic cards (code was obtained from
here)
To enable native power management you should use proper mac model + HPET enabled. To enable C-States you must have LPC working on your system. It could be enabled via DSDT mod or injector.
To activate P-States generation add "
GeneratePStates"="
Yes" option into boot.plist. To activate C-States generation add "
GenerateCStates"="
Yes" option into boot.plist. Those features are not activated by default!
Sources available
here. The name of the project is Chameleon-Mozodojo.
P-States generation algo based on original superhai's algo from VoodooPower project.
cham_rev218.zip ( 600.51K )
Number of downloads: 833 This post has been edited by Mojodojo: Jul 24 2010, 02:32 PM

Jul 20 2010, 10:00 AM

- Advanced Member
- Group: Staff
- Posts: 109
Nice work, I would like to see more of this, using SSDTs is a better way than patching the original DSDT in such cases, you probably already have seen this one, but I'll post the link anyway:
ACPI Generator from the coreboot project.
One thing I would really like to see is patching-on-the-fly a few things in the DSDT like the GNVS/BIOS starting address, this seems to change when you add/remove DIMMs.
Excerpts:
from my laptop:
CODE
OperationRegion (BIOS, SystemMemory, 0x7DFAE064, 0xFF)
from a MBP6,2:
CODE
OperationRegion (GNVS, SystemMemory, 0x8B6E6E18, 0x0161)

Jul 20 2010, 11:09 AM


- Member
- Group: Developer
- Posts: 66
QUOTE (Kabyl @ Jul 20 2010, 01:00 PM)

Nice work, I would like to see more of this, using SSDTs is a better way than patching the original DSDT in such cases, you probably already have seen this one, but I'll post the link anyway:
ACPI Generator from the coreboot project.
One thing I would really like to see is patching-on-the-fly a few things in the DSDT like the GNVS/BIOS starting address, this seems to change when you add/remove DIMMs.
Excerpts:
from my laptop:
CODE
OperationRegion (BIOS, SystemMemory, 0x7DFAE064, 0xFF)
from a MBP6,2:
CODE
OperationRegion (GNVS, SystemMemory, 0x8B6E6E18, 0x0161)
The simple solution: parse those values from the original dsdt before any patching or/and ovverride. After this, patch new dsdt with parsed values?

Jul 20 2010, 11:30 AM




- Advanced Member
- Group: Developer
- Posts: 5,574
QUOTE (Kabyl @ Jul 20 2010, 02:00 PM)

from my laptop:
CODE
OperationRegion (BIOS, SystemMemory, 0x7DFAE064, 0xFF)
from a MBP6,2:
CODE
OperationRegion (GNVS, SystemMemory, 0x8B6E6E18, 0x0161)
+1
CODE
OperationRegion (OSTY, SystemMemory, 0x37F7FF4C, 0x00000001)
OperationRegion (SMI1, SystemMemory, 0x37F7FDBC, 0x00000190)
After numerous patching of my DSDT I increased RAM and encounter non-working function. I had to find these values in DSDT.
But I have no idea how to correct it automatically... Compare BIOS DSDT with loaded from file? What names to check?

Jul 20 2010, 11:34 AM


- Member
- Group: Developer
- Posts: 66
We can parse and patch OperationRegions with well known names like: BIOS, GNVS, OSTY, SMI1. Make an array of these names, and patch differences automatically.

Jul 20 2010, 11:40 AM




- Advanced Member
- Group: Developer
- Posts: 5,574
All OperationRegions with SystemMemory and patch all differencies.

Jul 20 2010, 01:04 PM

- Advanced Member
- Group: Staff
- Posts: 109
QUOTE (Mojodojo @ Jul 20 2010, 12:09 PM)

The simple solution: parse those values from the original dsdt before any patching or/and ovverride. After this, patch new dsdt with parsed values?
Besides GNVS/BIOS/<whatever> everything else can be read from registers, so one needs to make a good DSDT with these OperationRegions set dynamically, or what do you think?

Jul 20 2010, 01:49 PM


- Member
- Group: Developer
- Posts: 66
QUOTE (Kabyl @ Jul 20 2010, 04:04 PM)

Besides GNVS/BIOS/<whatever> everything else can be read from registers, so one needs to make a good DSDT with these OperationRegions set dynamically, or what do you think?
I think it wouldn't be a big difference from parsing and patching some or whole OperationRegions found. We don't know where is the next OperationRegion appears so we need to check a whole DSDT, original one and a custom. Make an array with OperationRegion names and offsets. Compare differences and patch custom DSDT.
If I understand you correctly, you want to read values for some of OperationRegions from the specific registers? If it so, I tnink it's difficult, and I love simple solutions

Jul 20 2010, 02:00 PM




- Advanced Member
- Group: Developer
- Posts: 5,574
CODE
for(i=0; i<endOfDSDT;i++){
if((BIOSDSDTopCode[i]=OperationRegion) && (BIOSDSDTopCode[i+L]=SystemMemory)){
name=BIOSDSDTopCode[i+K];
addr=BIOSDSDTopCode[i+N];
for(j=0; i<endOfNewDSDT;i++){
if((newDSDTopCode[i]=OperationRegion) && (newDSDTopCode[i+L]=SystemMemory)
&&(name==newDSDTopCode[j+K])){
newDSDTopCode[j+N] = addr;
}
}
}

Jul 20 2010, 02:13 PM


- Member
- Group: Developer
- Posts: 66
QUOTE (Slice @ Jul 20 2010, 05:00 PM)

CODE
for(i=0; i<endOfDSDT;i++){
if((BIOSDSDTopCode[i]=OperationRegion) && (BIOSDSDTopCode[i+L]=SystemMemory)){
name=BIOSDSDTopCode[i+K];
addr=BIOSDSDTopCode[i+N];
for(j=0; i<endOfNewDSDT;i++){
if((newDSDTopCode[i]=OperationRegion) && (newDSDTopCode[i+L]=SystemMemory)
&&(name==newDSDTopCode[j+K])){
newDSDTopCode[j+N] = addr;
}
}
}
it's need some optimization. In this algo you parse custom DSDT every time you found OperationRegion in original DSDT

Jul 20 2010, 03:33 PM

- Advanced Member
- Group: Staff
- Posts: 109
QUOTE (Mojodojo @ Jul 20 2010, 02:49 PM)

If I understand you correctly, you want to read values for some of OperationRegions from the specific registers? If it so, I tnink it's difficult, and I love simple solutions

No, what I meant is, if someone is going to edit his DSDT, he could make it so that the OperationRegions are set by reading registers; RCBA addr, SMBus I/O port.. etc. Not to be done by the booter, but in the DSDT itself.
I hope it's clear now (?)

Jul 20 2010, 04:52 PM




- Advanced Member
- Group: Developer
- Posts: 5,574
QUOTE (Mojodojo @ Jul 20 2010, 06:13 PM)

it's need some optimization. In this algo you parse custom DSDT every time you found OperationRegion in original DSDT
It is not a problem for real programmers as we are, isn't it?
First scan byte by byte to find all regions. Second scan by table entries. Faster 10 times.
But I think my double cycle 20000x20000 will perform in L2 cache during 1sec.
QUOTE (Kabyl @ Jul 20 2010, 07:33 PM)

No, what I meant is, if someone is going to edit his DSDT, he could make it so that the OperationRegions are set by reading registers; RCBA addr, SMBus I/O port.. etc. Not to be done by the booter, but in the DSDT itself.
I hope it's clear now (?)

It's very hard task for almost all users except roots.
We are making an automatic solution for lamers.

Jul 20 2010, 05:11 PM


- Member
- Group: Developer
- Posts: 66
QUOTE (Kabyl @ Jul 20 2010, 06:33 PM)

No, what I meant is, if someone is going to edit his DSDT, he could make it so that the OperationRegions are set by reading registers; RCBA addr, SMBus I/O port.. etc. Not to be done by the booter, but in the DSDT itself.
I hope it's clear now (?)

I understand, I hope ^)
It's like a sections for SuperIO registers on some mobos.

Jul 20 2010, 07:21 PM




- Advanced Member
- Group: Developer
- Posts: 5,574
Ooops! Impossible! We need to know Names before search.

Jul 20 2010, 07:27 PM



- Member
- Group: Comrade
- Posts: 42
Quickly looking I see C1-C3 support, does this build support C4? I know most boards don't support four C-states but what about C1, C2 and C4.

Jul 20 2010, 11:38 PM

- Initiate
- Group: Comrade
- Posts: 20
Revision 346 doesn't give me CStates with DropSSDT either yes or no with a GA-EX58 MB's DSDT with a standard PR scope.
However, when clocked over a certain point (148x20 or 2.96 GHz for a i7 920 or Xeon W3520 CPU), the OS doesn't see the CStates available to it anyways.
Memory detection didn't work either, but does work with AsereBLN's version.

Jul 21 2010, 04:45 AM


- Member
- Group: Comrade
- Posts: 46
I have not played around with compiling sources in OSX yet only Linux. Is it kinda the same?
Anyhow does anyone have a link to the i386 binary?
This post has been edited by osxfr33k: Jul 21 2010, 04:46 AM
Chameleon 2 RC5 Generally the latest using Chameleon Wizard
Auto Patched DSDTs
5 towers: Asus Maximux Formula Special Editions with Rampage Formula Bios conversion, Gigabyte GA-EP35-DS4, GA-EP45-UD3P, GA-G41M-ES2L and Newcomer GA-Z68X-UD4-B3
4 Quad Core Processors: QX6850/Q9650/Q6600/i7-2600K
MAC PRO EARLY 2008 Xeon 8 Core/10GB RAM/4TB Seagates
Asus G51JX i7-720QM. 8GB Kingston Ram. HM55 Chipset
Asus Gamers Notebook G74SX-XT1 i7-2630QM. 16GB Samsung. HM65 Chipset
Dell Laptops D820, D830, XPS M1530

Jul 21 2010, 05:07 AM


- Member
- Group: Developer
- Posts: 66
QUOTE (Slice @ Jul 20 2010, 10:21 PM)

Ooops! Impossible! We need to know Names before search.
it' not required to know a name. We can search for OperationalRegionOp (0x830b) and parse the name.

Jul 21 2010, 07:26 AM

- Advanced Member
- Group: Staff
- Posts: 109
The way I see it could be done is, parsing both the original and modified DSDT and building 2 arrays of a type with 2 pointers; each pointing to the OperationRegion's name and address, then we go over the 2 arrays, compare and patch...
CODE
typedef struct {
char *name;
void *addr;
} operationRegion;
#define OP_REG_MAX_NUM 20 // enough?
operationRegion orgOperationRegions[OP_REG_MAX_NUM];
operationRegion modOperationRegions[OP_REG_MAX_NUM];
int buildOperationRegionsFromTable(operationRegion opRegs[], void *table);
int fixOperationRegions(operationRegion orgOpRegs[], operationRegion modOpRegs[]);

Jul 21 2010, 07:37 AM


- Member
- Group: Developer
- Posts: 66
QUOTE (Kabyl @ Jul 21 2010, 10:26 AM)

The way I see it could be done is, parsing both the original and modified DSDT and building 2 arrays of a type with 2 pointers; each pointing to the OperationRegion's name and address, then we go over the 2 arrays, compare and patch...
CODE
typedef struct {
char *name;
void *addr;
} operationRegion;
#define OP_REG_MAX_NUM 20 // enough?
operationRegion orgOperationRegions[OP_REG_MAX_NUM];
operationRegion modOperationRegions[OP_REG_MAX_NUM];
int buildOperationRegionsFromTable(operationRegion opRegs[], void *table);
int fixOperationRegions(operationRegion orgOpRegs[], operationRegion modOpRegs[]);
Yes, something like this. Is it really necessary? It may increase system startup time.