Understanding ATI assembler and AtomDis
I need little help to understand disassembled code from by BIOS. What does actually mean second column in AtomDis c output? 0009: 0308008001 MOVE work[00] [..XX] <- reg[0180] [..XX] I don't understand that 0308008001. Next, what is work[00]? Is this just some not used register for calculations? Am I right? Then how does MOVE work? MOVE work[00] [..XX] <- reg[0180] [..XX] Let's say I get following output: # rhd_dump -r 0180,0184 01:00.0 0x0180: 0x01234567 0x0184: 0x89ABCDE does it mean sth following: 0x0180: 0x01 0x0181: 0x23 0x0182: 0x45 0x0183: 0x67 ? If so, what is [..XX] part of 0x0180? Shuld I treat 0x0180 as 0x0001 and [..XX] means 0x01 then? Finally, how does work DIV WS_QUOT/LOW32 [XXXX] <- 00000008 ? -- Rafał Miłecki -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/5/20 Rafał Miłecki <zajec5@gmail.com>:
I need little help to understand disassembled code from by BIOS.
What does actually mean second column in AtomDis c output? 0009: 0308008001 MOVE work[00] [..XX] <- reg[0180] [..XX] I don't understand that 0308008001.
That's the bytecode for the instruction. The decoded instruction is written next to it. It's saying move the lower 2 bytes of register 0x180 to the lower two bytes of workspace 0.
Next, what is work[00]? Is this just some not used register for calculations? Am I right?
In atom you have param space (the inputs to the command tables), work space (local storage used by the interpreter when executing scripts and then the various registers: reg (direct mmio space), pll (indirect pll register space), mc (indirect memory controller register space).
Then how does MOVE work? MOVE work[00] [..XX] <- reg[0180] [..XX] Let's say I get following output: # rhd_dump -r 0180,0184 01:00.0 0x0180: 0x01234567 0x0184: 0x89ABCDE does it mean sth following: 0x0180: 0x01 0x0181: 0x23 0x0182: 0x45 0x0183: 0x67 ? If so, what is [..XX] part of 0x0180? Shuld I treat 0x0180 as 0x0001 and [..XX] means 0x01 then?
The direct registers are listed as dword offsets in atom so you have to multiply them by 4 to get the byte offsets. so 0x180 in atom is 0x600 is byte offsets. PLL and MC registers are indirect indexes so the offsets are index values. Registers are 32 bits, and the atom ops can operate on individual bytes or groups of bytes. In this case the op is operating on the lower two bytes (hence the ..XX). In your example the lower two bytes are 0x4567. So this op would roughly translate into: work[00] = (work[00] & 0xffff0000) | (INREG(0x600) & 0xffff);
Finally, how does work DIV WS_QUOT/LOW32 [XXXX] <- 00000008 ?
Divide the current workspace value by 8. Alex -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
W dniu 20 maja 2009 15:45 użytkownik Alex Deucher <alexdeucher@gmail.com> napisał:
2009/5/20 Rafał Miłecki <zajec5@gmail.com>:
Then how does MOVE work? MOVE work[00] [..XX] <- reg[0180] [..XX] Let's say I get following output: # rhd_dump -r 0180,0184 01:00.0 0x0180: 0x01234567 0x0184: 0x89ABCDE does it mean sth following: 0x0180: 0x01 0x0181: 0x23 0x0182: 0x45 0x0183: 0x67 ? If so, what is [..XX] part of 0x0180? Shuld I treat 0x0180 as 0x0001 and [..XX] means 0x01 then?
Registers are 32 bits, and the atom ops can operate on individual bytes or groups of bytes. In this case the op is operating on the lower two bytes (hence the ..XX). In your example the lower two bytes are 0x4567.
You say registers are 32bits... that's fine, for example my 0x0185 is 0xAB, so 2*16bits = 32bits. Alright. But next you say two lower bytes (2B == 16b) of my example 0x0180 (0x01234567) are 0x4567. Here I'm lost. 4*16bits = 64bits. That means 8B, not 2B :| Could you explain that one more please, so I could try to understand that?
Finally, how does work DIV WS_QUOT/LOW32 [XXXX] <- 00000008 ?
Divide the current workspace value by 8.
So WS_QUOT is kind of pointer to current workspace? Does "current workspace" always mean work[00] or may is be 01/02/... sometimes? What determines which workspace will be used for DIV? Or maybe WS_QUOT/LOW32 means work[00] and WS_QUOTE/HIGH32 means work[01]? Are there some special tricks when dividing in atom bios? I created almost working GetEngineClock, but is misses 10^1: http://bugs.freedesktop.org/show_bug.cgi?id=21812 -- Rafał Miłecki -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On May 20, 09 19:03:12 +0200, Rafał Miłecki wrote:
MOVE work[00] [..XX] <- reg[0180] [..XX] Registers are 32 bits, and the atom ops can operate on individual bytes or groups of bytes. In this case the op is operating on the lower two bytes (hence the ..XX). In your example the lower two bytes are 0x4567.
You say registers are 32bits... that's fine, for example my 0x0185 is 0xAB, so 2*16bits = 32bits. Alright.
But next you say two lower bytes (2B == 16b) of my example 0x0180 (0x01234567) are 0x4567. Here I'm lost. 4*16bits = 64bits. That means 8B, not 2B :|
Remember, the operation was working on different registers than your original dumps due to the *4.
Finally, how does work DIV WS_QUOT/LOW32 [XXXX] <- 00000008 Divide the current workspace value by 8.
5.2.7DIV_ Performs an arithmetical “DIV” operation between the source and destination. Result of division will be stored into dedicated Work Space location, indexed by WS_QUOTIENT definitions. Reminder of division will be stored into dedicated Work Space location, indexed by WS_REMINDER definitions. So this devides WS_QUOTIENT by 8, and stors that in WS_QUOTIENT and the remainder in WS_REMINDER. The work register indices are defined in AtomDis/atombios_consts.h CU Matthias -- Matthias Hopf <mhopf@suse.de> __ __ __ Maxfeldstr. 5 / 90409 Nuernberg (_ | | (_ |__ mat@mshopf.de Phone +49-911-74053-715 __) |_| __) |__ R & D www.mshopf.de -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/5/20 Rafał Miłecki <zajec5@gmail.com>:
W dniu 20 maja 2009 15:45 użytkownik Alex Deucher <alexdeucher@gmail.com> napisał:
2009/5/20 Rafał Miłecki <zajec5@gmail.com>:
Then how does MOVE work? MOVE work[00] [..XX] <- reg[0180] [..XX] Let's say I get following output: # rhd_dump -r 0180,0184 01:00.0 0x0180: 0x01234567 0x0184: 0x89ABCDE does it mean sth following: 0x0180: 0x01 0x0181: 0x23 0x0182: 0x45 0x0183: 0x67 ? If so, what is [..XX] part of 0x0180? Shuld I treat 0x0180 as 0x0001 and [..XX] means 0x01 then?
Registers are 32 bits, and the atom ops can operate on individual bytes or groups of bytes. In this case the op is operating on the lower two bytes (hence the ..XX). In your example the lower two bytes are 0x4567.
You say registers are 32bits... that's fine, for example my 0x0185 is 0xAB, so 2*16bits = 32bits. Alright.
But next you say two lower bytes (2B == 16b) of my example 0x0180 (0x01234567) are 0x4567. Here I'm lost. 4*16bits = 64bits. That means 8B, not 2B :|
Could you explain that one more please, so I could try to understand that?
0x180 is the offset of the regsiter in dwords. 0x180 * 4 = 0x600 = offset in bytes since 1 dword = 4 bytes. The register offset defines the register's location relative to the start of register aperture. so the register in question is 0x180 dwords from the start of the aperture or 0x600 bytes. Each register is 32 bits, so the lower two bytes are 0x4567. Alex -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
W dniu 20 maja 2009 19:34 użytkownik Alex Deucher <alexdeucher@gmail.com> napisał:
2009/5/20 Rafał Miłecki <zajec5@gmail.com>:
Could you explain that one more please, so I could try to understand that?
0x180 is the offset of the regsiter in dwords. 0x180 * 4 = 0x600 = offset in bytes since 1 dword = 4 bytes. The register offset defines the register's location relative to the start of register aperture. so the register in question is 0x180 dwords from the start of the aperture or 0x600 bytes.
OK, understand that already, thanks.
Each register is 32 bits, so the lower two bytes are 0x4567.
That was tricky part for me. I would call 0x4567 in any following way: a) last 2 dwords b) last 4 hexs c) last 8 bytes d) last 64 bits but not "two bytes". Anyway, I get this now, thanks for explaining :) -- Rafał Miłecki -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/5/20 Rafał Miłecki <zajec5@gmail.com>:
W dniu 20 maja 2009 19:34 użytkownik Alex Deucher <alexdeucher@gmail.com> napisał:
2009/5/20 Rafał Miłecki <zajec5@gmail.com>:
Could you explain that one more please, so I could try to understand that?
0x180 is the offset of the regsiter in dwords. 0x180 * 4 = 0x600 = offset in bytes since 1 dword = 4 bytes. The register offset defines the register's location relative to the start of register aperture. so the register in question is 0x180 dwords from the start of the aperture or 0x600 bytes.
OK, understand that already, thanks.
Each register is 32 bits, so the lower two bytes are 0x4567.
That was tricky part for me. I would call 0x4567 in any following way: a) last 2 dwords b) last 4 hexs c) last 8 bytes d) last 64 bits
?
but not "two bytes". Anyway, I get this now, thanks for explaining :)
But it is 2 bytes. The entire register is only 1 dword (32 bits or 4 bytes): 0x01234567. You can break that down as 4 bytes: 0x01 0x23 0x45 0x67 so the lower two bytes are: 0x4567 Alex -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On May 20, 09 09:45:47 -0400, Alex Deucher wrote:
2009/5/20 Rafał Miłecki <zajec5@gmail.com>:
What does actually mean second column in AtomDis c output? 0009: 0308008001 MOVE work[00] [..XX] <- reg[0180] [..XX] I don't understand that 0308008001.
That's the bytecode for the instruction. The decoded instruction is written next to it.
You should note that this is not the "official" ATI notion - I didn't know the syntax at the time of writing, and wanted to create one that is as trivially readable as possible. That's why I used '<-' and not ',' - you always wonder whether it's source first or dest first in this case ;-)
Next, what is work[00]? Is this just some not used register for calculations? Am I right?
Alex, is the AtomBIOS language description available online? I don't remember, that doc is certainly helpful in understanding the language.
MOVE work[00] [..XX] <- reg[0180] [..XX] The direct registers are listed as dword offsets in atom so you have to multiply them by 4 to get the byte offsets. so 0x180 in atom is
There is also a runtime option to do the multiplication for you.
Finally, how does work DIV WS_QUOT/LOW32 [XXXX] <- 00000008
Divide the current workspace value by 8.
Be aware that WS_QUOT/LOW32 is actually a special work[] register (forgot the number), and there are more magical work[] registers. It's the weirdest and most difficult to understand part of the language. Matthias -- Matthias Hopf <mhopf@suse.de> __ __ __ Maxfeldstr. 5 / 90409 Nuernberg (_ | | (_ |__ mat@mshopf.de Phone +49-911-74053-715 __) |_| __) |__ R & D www.mshopf.de -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
W dniu 20 maja 2009 19:18 użytkownik Matthias Hopf <mhopf@suse.de> napisał:
On May 20, 09 09:45:47 -0400, Alex Deucher wrote:
Next, what is work[00]? Is this just some not used register for calculations? Am I right?
Alex, is the AtomBIOS language description available online? I don't remember, that doc is certainly helpful in understanding the language.
Would be nice to see that. Thanks for explaining DIV :) -- Rafał Miłecki -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
There is one more command I don't understand: SET_REG_BLOCK 0000 SET_REG_BLOCK 0001 what does it do? -- Rafał Miłecki -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On Jun 05, 09 19:58:35 +0200, Rafał Miłecki wrote:
There is one more command I don't understand:
SET_REG_BLOCK 0000 SET_REG_BLOCK 0001
5.3.4 SET_REG_BLOCK This command sets up a non-zero index for block(n) register programming. Default value of this command is 0. To program a register in a table, Parser uses MM_INDEX+ Reg_Block Index + RegIndex. Through this way, a table can be used to program block(n) registers without duplicating the table. So in your case this basically adds 0 or 1 to the registers that are programmed. CU Matthias -- Matthias Hopf <mhopf@suse.de> __ __ __ Maxfeldstr. 5 / 90409 Nuernberg (_ | | (_ |__ mat@mshopf.de Phone +49-911-74053-715 __) |_| __) |__ R & D www.mshopf.de -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/6/5 Rafał Miłecki <zajec5@gmail.com>:
There is one more command I don't understand:
SET_REG_BLOCK 0000 SET_REG_BLOCK 0001
what does it do?
There are lots of sets of registers that have multiple instances in register space (e.g., there are two identical sets of CRTC registers, one for each CRTC, DACs and DIG PHYs on newer chips, etc.). That command is used to select the offset added to the registers in order to access different register blocks. Take a look at SetCRTC_Timing: 0009: 3da50400 COMP param[04] [.X..] <- 00 000d: 441300 JUMP_Equal 0013 0010: 3a0002 SET_REG_BLOCK 0200 if you've selected crtc 1, add an offset of 0x200 dwords (0x800 bytes) to the registers, if it's crtc 0, do not. Alex -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
W dniu 5 czerwca 2009 20:11 użytkownik Alex Deucher <alexdeucher@gmail.com> napisał:
2009/6/5 Rafał Miłecki <zajec5@gmail.com>:
There is one more command I don't understand:
SET_REG_BLOCK 0000 SET_REG_BLOCK 0001
what does it do?
There are lots of sets of registers that have multiple instances in register space (e.g., there are two identical sets of CRTC registers, one for each CRTC, DACs and DIG PHYs on newer chips, etc.). That command is used to select the offset added to the registers in order to access different register blocks. Take a look at SetCRTC_Timing:
0009: 3da50400 COMP param[04] [.X..] <- 00 000d: 441300 JUMP_Equal 0013 0010: 3a0002 SET_REG_BLOCK 0200
if you've selected crtc 1, add an offset of 0x200 dwords (0x800 bytes) to the registers, if it's crtc 0, do not.
Alex
Thanks for explaination with nice example. Nice way to handle 2 pll/crtc/... in one code :) Still one more (hopefully last?) question. How do work (and what is difference) TEST and COMP? param[00] == 0x12345678 X: 4be50004 TEST param[00] [X...] <- 04 Y: 441700 JUMP_Equal 0017 12 != 04, so jump won't happen, right? param[00] == 0x12345678 0017: 3d0d000000 COMP param[00] [..XX] <- 0000 001c: 448c00 JUMP_Equal 008c 5678 != 0000, so jump won't happen, right? Actually I think I'm wrong in at least one of examples above :) -- Rafał Miłecki -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/6/5 Rafał Miłecki <zajec5@gmail.com>:
W dniu 5 czerwca 2009 20:11 użytkownik Alex Deucher <alexdeucher@gmail.com> napisał:
2009/6/5 Rafał Miłecki <zajec5@gmail.com>:
There is one more command I don't understand:
SET_REG_BLOCK 0000 SET_REG_BLOCK 0001
what does it do?
There are lots of sets of registers that have multiple instances in register space (e.g., there are two identical sets of CRTC registers, one for each CRTC, DACs and DIG PHYs on newer chips, etc.). That command is used to select the offset added to the registers in order to access different register blocks. Take a look at SetCRTC_Timing:
0009: 3da50400 COMP param[04] [.X..] <- 00 000d: 441300 JUMP_Equal 0013 0010: 3a0002 SET_REG_BLOCK 0200
if you've selected crtc 1, add an offset of 0x200 dwords (0x800 bytes) to the registers, if it's crtc 0, do not.
Alex
Thanks for explaination with nice example. Nice way to handle 2 pll/crtc/... in one code :)
Still one more (hopefully last?) question. How do work (and what is difference) TEST and COMP?
COMP looks to see if src and dst are equal, TEST tests using logical AND. You can follow the logic of any of these commands by looking at AtomBios/CD_Operations.c. See ProcessCompare() and ProcessTest().
param[00] == 0x12345678 X: 4be50004 TEST param[00] [X...] <- 04 Y: 441700 JUMP_Equal 0017 12 != 04, so jump won't happen, right?
This would be equate to: (0x12 & 0x4) ? NotEqual : Equal So the jump would happen.
param[00] == 0x12345678 0017: 3d0d000000 COMP param[00] [..XX] <- 0000 001c: 448c00 JUMP_Equal 008c 5678 != 0000, so jump won't happen, right?
correct. Alex -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
I have one more question about AtomBIOS commands. Could you explain paramspace, please? I dumped SetEngineClock operation from my AtomBIOS and it uses: param[00] param[01] param[02] AFAIU each param is 4 dwords, so 32bit. But it seems we pass only one ULONG as argument (param): /****************************************************************************/ // Structures used by SetEngineClockTable /****************************************************************************/ typedef struct _SET_ENGINE_CLOCK_PARAMETERS { ULONG ulTargetEngineClock; //In 10Khz unit }SET_ENGINE_CLOCK_PARAMETERS; typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION { ULONG ulTargetEngineClock; //In 10Khz unit COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; }SET_ENGINE_CLOCK_PS_ALLOCATION; does it mean param[01] and param[02] are there just like workspace variables? -- Rafał -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
W dniu 31 stycznia 2010 00:14 użytkownik Rafał Miłecki <zajec5@gmail.com> napisał:
I have one more question about AtomBIOS commands. Could you explain paramspace, please?
I dumped SetEngineClock operation from my AtomBIOS and it uses: param[00] param[01] param[02]
AFAIU each param is 4 dwords, so 32bit. But it seems we pass only one ULONG as argument (param):
/****************************************************************************/ // Structures used by SetEngineClockTable /****************************************************************************/ typedef struct _SET_ENGINE_CLOCK_PARAMETERS { ULONG ulTargetEngineClock; //In 10Khz unit }SET_ENGINE_CLOCK_PARAMETERS;
typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION { ULONG ulTargetEngineClock; //In 10Khz unit COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; }SET_ENGINE_CLOCK_PS_ALLOCATION;
does it mean param[01] and param[02] are there just like workspace variables?
Ahh, it reads only param[00] from but computes other params that are used in subcalls like: 000e: 523c CALL_TABLE 3c (ComputeMemoryEnginePLL) :) -- Rafał -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
W dniu 31 stycznia 2010 00:38 użytkownik Rafał Miłecki <zajec5@gmail.com> napisał:
W dniu 31 stycznia 2010 00:14 użytkownik Rafał Miłecki <zajec5@gmail.com> napisał:
I have one more question about AtomBIOS commands. Could you explain paramspace, please?
I dumped SetEngineClock operation from my AtomBIOS and it uses: param[00] param[01] param[02]
AFAIU each param is 4 dwords, so 32bit. But it seems we pass only one ULONG as argument (param):
/****************************************************************************/ // Structures used by SetEngineClockTable /****************************************************************************/ typedef struct _SET_ENGINE_CLOCK_PARAMETERS { ULONG ulTargetEngineClock; //In 10Khz unit }SET_ENGINE_CLOCK_PARAMETERS;
typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION { ULONG ulTargetEngineClock; //In 10Khz unit COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; }SET_ENGINE_CLOCK_PS_ALLOCATION;
does it mean param[01] and param[02] are there just like workspace variables?
Ahh, it reads only param[00] from but computes other params that are used in subcalls like: 000e: 523c CALL_TABLE 3c (ComputeMemoryEnginePLL) :)
Hopefully final (real) question: SetEngineClock takes only one param which is param[00] I believe. Following are 3 first lines of SetEngineClock: 0006: 02010100 MOVE param[01] [XXXX] <- param[00] [XXXX] 000a: 02250202 MOVE param[02] [...X] <- 02 000e: 523c CALL_TABLE 3c (ComputeMemoryEnginePLL) ComputeMemoryEnginePLL takes 2 params. In this case, how ComputeMemoryEnginePLL is called from SetEngineClock? Is that: ComputeMemoryEnginePLL(param[00], param[01]) ? or maybe: ComputeMemoryEnginePLL(param[01], param[02]) ? -- Rafał -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On Sun, Jan 31, 2010 at 12:44:16AM +0100, Rafał Miłecki wrote:
W dniu 31 stycznia 2010 00:38 użytkownik Rafał Miłecki <zajec5@gmail.com> napisał:
W dniu 31 stycznia 2010 00:14 użytkownik Rafał Miłecki <zajec5@gmail.com> napisał:
I have one more question about AtomBIOS commands. Could you explain paramspace, please?
I dumped SetEngineClock operation from my AtomBIOS and it uses: param[00] param[01] param[02]
AFAIU each param is 4 dwords, so 32bit. But it seems we pass only one ULONG as argument (param):
/****************************************************************************/ // Structures used by SetEngineClockTable /****************************************************************************/ typedef struct _SET_ENGINE_CLOCK_PARAMETERS { ULONG ulTargetEngineClock; //In 10Khz unit }SET_ENGINE_CLOCK_PARAMETERS;
typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION { ULONG ulTargetEngineClock; //In 10Khz unit COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; }SET_ENGINE_CLOCK_PS_ALLOCATION;
does it mean param[01] and param[02] are there just like workspace variables?
Ahh, it reads only param[00] from but computes other params that are used in subcalls like: 000e: 523c CALL_TABLE 3c (ComputeMemoryEnginePLL) :)
Hopefully final (real) question:
SetEngineClock takes only one param which is param[00] I believe. Following are 3 first lines of SetEngineClock: 0006: 02010100 MOVE param[01] [XXXX] <- param[00] [XXXX] 000a: 02250202 MOVE param[02] [...X] <- 02 000e: 523c CALL_TABLE 3c (ComputeMemoryEnginePLL)
ComputeMemoryEnginePLL takes 2 params. In this case, how ComputeMemoryEnginePLL is called from SetEngineClock? Is that: ComputeMemoryEnginePLL(param[00], param[01]) ? or maybe: ComputeMemoryEnginePLL(param[01], param[02]) ?
The second, iirc. Iirc, the disassembled code for ComputeMemoryEnginePLL will be using param[00] and param[01] from its point of view. This POV is the param pointer of its caller, plus the number of arguments its caller had. Atombios bytecode is not always very obvious (i'm sure you know about this one glaring/huge logic inversion error), but it beats having to read x86 :) Luc Verhaegen. -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
W dniu 31 stycznia 2010 01:16 użytkownik Luc Verhaegen <libv@skynet.be> napisał:
On Sun, Jan 31, 2010 at 12:44:16AM +0100, Rafał Miłecki wrote:
W dniu 31 stycznia 2010 00:38 użytkownik Rafał Miłecki <zajec5@gmail.com> napisał:
W dniu 31 stycznia 2010 00:14 użytkownik Rafał Miłecki <zajec5@gmail.com> napisał:
I have one more question about AtomBIOS commands. Could you explain paramspace, please?
I dumped SetEngineClock operation from my AtomBIOS and it uses: param[00] param[01] param[02]
AFAIU each param is 4 dwords, so 32bit. But it seems we pass only one ULONG as argument (param):
/****************************************************************************/ // Structures used by SetEngineClockTable /****************************************************************************/ typedef struct _SET_ENGINE_CLOCK_PARAMETERS { ULONG ulTargetEngineClock; //In 10Khz unit }SET_ENGINE_CLOCK_PARAMETERS;
typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION { ULONG ulTargetEngineClock; //In 10Khz unit COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; }SET_ENGINE_CLOCK_PS_ALLOCATION;
does it mean param[01] and param[02] are there just like workspace variables?
Ahh, it reads only param[00] from but computes other params that are used in subcalls like: 000e: 523c CALL_TABLE 3c (ComputeMemoryEnginePLL) :)
Hopefully final (real) question:
SetEngineClock takes only one param which is param[00] I believe. Following are 3 first lines of SetEngineClock: 0006: 02010100 MOVE param[01] [XXXX] <- param[00] [XXXX] 000a: 02250202 MOVE param[02] [...X] <- 02 000e: 523c CALL_TABLE 3c (ComputeMemoryEnginePLL)
ComputeMemoryEnginePLL takes 2 params. In this case, how ComputeMemoryEnginePLL is called from SetEngineClock? Is that: ComputeMemoryEnginePLL(param[00], param[01]) ? or maybe: ComputeMemoryEnginePLL(param[01], param[02]) ?
The second, iirc. Iirc, the disassembled code for ComputeMemoryEnginePLL will be using param[00] and param[01] from its point of view. This POV is the param pointer of its caller, plus the number of arguments its caller had.
Atombios bytecode is not always very obvious (i'm sure you know about this one glaring/huge logic inversion error), but it beats having to read x86 :)
Thank you :) -- Rafał -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
participants (4)
-
Alex Deucher
-
Luc Verhaegen
-
Matthias Hopf
-
Rafał Miłecki