Hi all,
I know bit more about IMC now (I did some research in this direction).
All PCI and IO accesses following are byte-width.
There are several IO ports used, which will be defined here: NMI_Status 0x0061 NMI_Enable 0x0070 RtcDataPort 0x0071 Isa_Misc 0x0C6F PM_Index 0x0CD6 PM_Data 0x0CD7
One PM register, accessed via the PM_Index and PM_Data ports above, is used: TESTENABLE 0x53 SMI_Disable (1 << 3)
This is the board-enable procedure:
- Check LPC/ISA Bridge register 40 (00:14.03[40]) bit 7 (IntegratedImcPresent)
1.a. If the IntegratedImcPresent bit is not set, skip to step 12
Yes also noted as "IMC active" not yet sure if IMC is in "IDLE" if it is unset. Most likely yes.
- Disable SMIs:
2.a. Write TESTENABLE to PM_Index 2.b. Read PM_Data 2.c. Set the SMI_Disable bit 2.d. Write the new value to PM_Data 3. Clear bit 3 in SMBus/ACPI register 43 (00:14.00[43]) 4. Check SMBus/ACPI register 20 (00:14.00[20]) bit 1 4.a. If it is set, skip to step 11 5. Set bit 1 in SMBus/ACPI register 20 (00:14.00[20]) 6. Do some IO: 6.a. Write 0x7D to NMI_Enable 6.b. Read NMI_Status 6.c. Read NMI_Status 6.d. Read RtcDataPort 6.d.1. If the value returned has bit 3 clear, skip to step 11 7. Check LPC/ISA Bridge register 40 (00:14.03[40]) bit 7 (IntegratedImcPresent) 7.a. If the IntegratedImcPresent bit is not set, skip to step 11
Yes so this seems yet another check if IMC went to IDLE (this is like x86 HLT, CLK is stopped but IRQs will wakup the 8051).
- Do some IO:
I know what it is. It is mailbox interface to the firmware. I described that here: http://www.coreboot.org/AMD_IMC the 0x3e base is set in LDN9 as mailbox base. You should obtain this address from the LDN9.
8.a. Write 0x82 to 0x003E 8.b. Write 0x00 to 0x003F 8.c. Write 0x83 to 0x003E 8.d. Write 0xB4 to 0x003F
Are you sure the 0x00 goes to 82? and B4 goes to 83? While analyzing the firmware I think it was vice-versa. I can recheck this.
8.e. Write 0x84 to 0x003E 8.f. Write 0x00 to 0x003F 8.g. Write 0x80 to 0x003E 8.h. Write 0x96 to 0x003F
The command is 0x96 which means go to sleep. You should check in 0x82 for 0xfa maybe? It means firmware acked command.
- Loop: Set the loop variable to 4000 (0xFA0)
9.a. Busy-poll bit 4 (RefClk) of NmiStatus until it is set 9.b. Decrement the loop variable and exit the loop if it is 0 9.c. Busy-poll bit 4 (RefClk) of NmiStatus until it is clear 9.d. Decrement the loop variable and exit the loop if it is 0 10. Loop: 10.a. Loop: Set the loop variable to 66 (0x42) 10.a.1. Busy-poll bit 4 (RefClk) of NmiStatus until it is set 10.a.2. Decrement the loop variable and exit the loop if it is 0 10.a.3. Busy-poll bit 4 (RefClk) of NmiStatus until it is clear 10.a.4. Decrement the loop variable and exit the loop if it is 0 10.b. Write 0x82 to 0x003E 10.c. Read 0x003F and exit the loop if it is 0xFA
Yes this just waits for firmware. Maybe it is using refclk as timeout value which should be up to 100ms.
- Set bit 3 in SMBus/ACPI register 43 (00:14.00[43])
Yes this makes me wonder what does firmware do with the bit. It should enables the writes to the registers. Maybe firmware uses that as scratchpad?
- Set bit 0 in SMBus/ACPI register 79 (00:14.00[79])
- Set bit 6 in Isa_Misc
Hm the bit6 is documented in SB600 and it shhould be used only if PCI bus is used instead of flash.?
Thanks Rudolf