Zenith432 Posted May 17, 2016 Share Posted May 17, 2016 Slice: The crash experienced by calibre comes from GetTagCount() in rEFIt_UEFI/Platform/plist.c... INTN GetTagCount( TagPtr dict ) { INTN count = 0; TagPtr tagList, tag; if (dict->type != kTagTypeDict && dict->type != kTagTypeArray) { return 0; } tag = 0; tagList = dict->tag; The value in ESI 0xFFFFFFFF is dict->tag. I've searched the code in plist.c, and I see it using NULL to mark this field as having no value - but I don't see how it could possibly get assigned the value 0xFFFFFFFF. So I'm not sure what to do about it. [Note: the instruction that crashes "cmp dword [esi], 2" is the comparison tag->type != kTagTypeKey down the code] Link to comment Share on other sites More sharing options...
Micky1979 Posted May 17, 2016 Share Posted May 17, 2016 Can be a bad config.plist? The case the node is not an array as expected? Check is already there Link to comment Share on other sites More sharing options...
Zenith432 Posted May 17, 2016 Share Posted May 17, 2016 It's probably a malformed plist, but the parse code should not crash. Can be a bad config.plist? The case the node is not an array as expected? Link to comment Share on other sites More sharing options...
Micky1979 Posted May 17, 2016 Share Posted May 17, 2016 What I can't see is the check if dict exists or not if ( dict->type != kTagTypeDict && dict->type != kTagTypeArray) { return 0; } ie before any "->" operator, but offcourse if does not exist is not an array anyway EDIT ESI...Is a bad string! like the case contains special characters that xml.c can't handle or is null. 1 Link to comment Share on other sites More sharing options...
Slice Posted May 17, 2016 Share Posted May 17, 2016 I am not sure if this is the case but I commit initializing local variables. (3531) It will be better to have such problem on own computer to reproduce the crash and debug it. For Zenith432/Mickey1979 x32.png upload, please, your quirky config.plist. 1 Link to comment Share on other sites More sharing options...
calibre™ Posted May 17, 2016 Share Posted May 17, 2016 @Slice I have been using this config without issue Calibre_config.zip Link to comment Share on other sites More sharing options...
Micky1979 Posted May 17, 2016 Share Posted May 17, 2016 maybe is not the only plist read by Clover, can be also a theme plist. Link to comment Share on other sites More sharing options...
calibre™ Posted May 17, 2016 Share Posted May 17, 2016 Theme.plist is untouched from bootcamp. No difference even changing theme. Il try to check older builds if i can find time later. Link to comment Share on other sites More sharing options...
Needy Posted May 17, 2016 Share Posted May 17, 2016 Can you show that Windows booted by Clover shows other hardware information then booted directly from BIOS? I mentioned it earlier, but I'll say it again, what you have done is quite enough and I said, thank you, as well. After some research I found that the Unknown memory type is a windows' issue not clover's, to be more specific not UEFI firmware's that starts windows. You asked for differences in hardware information. I found one, not significant. If windows is booted from bios screen, so to speak, the hardware reserved memory is 1.5MB. However, if I boot windows from clover's GUI, the hardware reserved memory is 6.9MB. Below are 2 screenshots. Best regards. Link to comment Share on other sites More sharing options...
The Real Deal Posted May 17, 2016 Share Posted May 17, 2016 Hi fellas, I use R3251 for a while and it goes along with my GTX 690. Today, i wanted to test newer revisions of clover but unfortunately with R3526 and R3424, graphics drivers are loaded but black screen on desktop. Switch back to R3251, all is fine. Any idea? I wasn't there for a long time. EDIT : R3526 with my 8400 GS all ok. Link to comment Share on other sites More sharing options...
Slice Posted May 17, 2016 Share Posted May 17, 2016 Hi fellas, I use R3251 for a while and it goes along with my GTX 690. Today, i wanted to test newer revisions of clover but unfortunately with R3526 and R3424, graphics drivers are loaded but black screen on desktop. Switch back to R3251, all is fine. Any idea? I wasn't there for a long time. EDIT : R3526 with my 8400 GS all ok. See changes explained here #18 Link to comment Share on other sites More sharing options...
Zenith432 Posted May 18, 2016 Share Posted May 18, 2016 It will be better to have such problem on own computer to reproduce the crash and debug it.Calibre sent me the binary for CLOVERIA32.efi that is crashing in post #824. I traced the return address on the stack,and the call to GetTagCount is coming from FillinCustomEntry() ... Prop = GetProperty (DictPointer, "VolumeType"); if (Prop != NULL && (Prop->type == kTagTypeString)) { if (AsciiStriCmp (Prop->string, "Internal") == 0) { Entry->VolumeType = VOLTYPE_INTERNAL; } else if (AsciiStriCmp (Prop->string, "External") == 0) { Entry->VolumeType = VOLTYPE_EXTERNAL; } else if (AsciiStriCmp (Prop->string, "Optical") == 0) { Entry->VolumeType = VOLTYPE_OPTICAL; } else if (AsciiStriCmp (Prop->string, "FireWire") == 0) { Entry->VolumeType = VOLTYPE_FIREWIRE; } } else { INTN i, Count = GetTagCount (Prop); <<<<<-------- if (Count > 0) { TagPtr Prop2 = NULL; for (i = 0; i < Count; i++) { ... The config.plist in post #833 doesn't have any custom entries. So it's loading the config.plist from somewhere else. PS: It doesn't crash on my system when I use Calibre's CLOVERIA32.efi and config.plist. Link to comment Share on other sites More sharing options...
Slice Posted May 18, 2016 Share Posted May 18, 2016 Calibre sent me the binary for CLOVERIA32.efi that is crashing in post #824. I traced the return address on the stack, and the call to GetTagCount is coming from FillinCustomEntry() ... Prop = GetProperty (DictPointer, "VolumeType"); if (Prop != NULL && (Prop->type == kTagTypeString)) { if (AsciiStriCmp (Prop->string, "Internal") == 0) { Entry->VolumeType = VOLTYPE_INTERNAL; } else if (AsciiStriCmp (Prop->string, "External") == 0) { Entry->VolumeType = VOLTYPE_EXTERNAL; } else if (AsciiStriCmp (Prop->string, "Optical") == 0) { Entry->VolumeType = VOLTYPE_OPTICAL; } else if (AsciiStriCmp (Prop->string, "FireWire") == 0) { Entry->VolumeType = VOLTYPE_FIREWIRE; } } else { INTN i, Count = GetTagCount (Prop); <<<<<-------- if (Count > 0) { TagPtr Prop2 = NULL; for (i = 0; i < Count; i++) { ... The config.plist in post #833 doesn't have any custom entries. So it's loading the config.plist from somewhere else. PS: It doesn't crash on my system when I use Calibre's CLOVERIA32.efi and config.plist. Weird!!!! Prop = GetProperty (DictPointer, "VolumeType"); if (Prop != NULL && (Prop->type == kTagTypeString)) { ... } else { INTN i, Count = GetTagCount (Prop); <<<<<-------- See! If Prop == NULL then GetTagCount (Prop) -> INTN GetTagCount( TagPtr dict ) { INTN count = 0; TagPtr tagList, tag; if (dict->type != kTagTypeDict && dict->type != kTagTypeArray) { Null pointer dereference! I will correct immediately. Thanks for find! 1 Link to comment Share on other sites More sharing options...
Zenith432 Posted May 18, 2016 Share Posted May 18, 2016 Slice, You're right (and Micky1979 too in post #831). The bug is that argument TagPtr dict to GetTagCount is NULL. I got confused about this. Because the parameter dict is passed in ECX, and ECX in the dump is 0x3C8CF0 - looking valid. So I mistook this pointer for dict. But now I look at the disassembly again. At the crash point ESI holds the value of dict->tag, which was taken from NULL->tag, and ECX holds the value of ESI->tagNext, which corresponds to statement tagList = tag->tagNext. So value of parameter dict is not in a register anymore at the crash point. dict is forgotten. The only place it's used later in the func is dict->type, which is remembered in register EDX (it's kTagTypeArray, but really taken from NULL parameter....) It's a freak accident that NULL->type ended up as kTagTypeArray. Otherwise GetTagCount would be exited with 0 as it should. 2 Link to comment Share on other sites More sharing options...
Slice Posted May 18, 2016 Share Posted May 18, 2016 Two same cases corrected in rev 3537. 3 Link to comment Share on other sites More sharing options...
The Real Deal Posted May 18, 2016 Share Posted May 18, 2016 See changes explained here #18 I'm f******** lost. What was the problem with old way? No matter how i struggle, clover beats me. Link to comment Share on other sites More sharing options...
Slice Posted May 18, 2016 Share Posted May 18, 2016 I'm f******** lost. What was the problem with old way? No matter how i struggle, clover beats me. Give me your config.plist I will look what was conflict with new Clover. Or you have too smart DSDT? Link to comment Share on other sites More sharing options...
joevt Posted May 19, 2016 Share Posted May 19, 2016 I compiled and edk2 updated itself and prompted me for a conflict. Which one is correct to select, TC or MC?The choices are documented athttp://www.tutorialspoint.com/svn/svn_resolve_conflicts.htm I would choose TC or TF if I know I didn't change that file. But before that I would go to the Finder and duplicate the Clover folder and manually compare after the update is complete to make sure something weird didn't happen and to see what everyone else was changing. May be timeouts? There is a check next cycle no such check. We can change 1000 -> 200 to test. The divide by 1000 is for converting Hz to kHz so that t is milliseconds instead of seconds. It would be faster and more accurate to multiply cycles by 1000 instead. Changing (t > 5) to (t > 200) would be the best way to increase the time out. I would replace the smb_read_byte routine with the following test version to see how the status changes (the long timeout will increase Clover startup time by several seconds so use this only for checking the behavior of the SMBus spd read routine): UINT8 smb_read_byte(UINT32 base, UINT8 adr, UINT16 cmd) { // INTN l1, h1, l2, h2; UINT64 t, t1, t2; UINT8 page; UINT8 c; UINT8 p; if (smbIntel) { p = 0xFF; t1 = AsmReadTsc(); //rdtsc(l1, h1); //IoWrite8(base + SMBHSTDAT, 0xFF); IoWrite8(base + SMBHSTSTS, 0xFF); // reset SMBus Controller (set busy) while (1) { // wait until host is not busy c = IoRead8(base + SMBHSTSTS); t2 = AsmReadTsc(); //rdtsc(l2, h2); t = DivU64x64Remainder(MultU64x32(t2 - t1, 1000), gCPUStructure.TSCFrequency, NULL); if (c != p) { DBG("t=%d adr=%02X cmd=%X host busy status %02X\n", (INTN)t, adr, cmd, c); p = c; } /* // This must be wrong. Bit 0 always appears to start as 0. if (~c & 1) { break; } */ if (t > 300) { if (~c & 1) break; DBG("t=%d adr=%02X cmd=%X host is busy for too long!\n", (INTN)t, adr, cmd); return 0xFF; // break } } page = (cmd >> 8) & 1; if (page != smbPage) { IoWrite8(base + SMBHSTCMD, 0x00); IoWrite8(base + SMBHSTADD, 0x6C + (page << 1)); // Set SPD Page Address #if 0 IoWrite8(base + SMBHSTCNT, 0x48); // Start + Byte Data Write // Don't use "Byte Data Write" because status goes from 0x41 (Busy) -> 0x44 (Error) #else IoWrite8(base + SMBHSTCNT, 0x40); // Start + Quick Write // status goes from 0x41 (Busy) -> 0x42 (Completed) #endif smbPage = page; p = 0xFF; t1 = AsmReadTsc(); while (1) { // wait until command finished c = IoRead8(base + SMBHSTSTS); t2 = AsmReadTsc(); t = DivU64x64Remainder(MultU64x32(t2 - t1, 1000), gCPUStructure.TSCFrequency, NULL); if (c != p) { DBG("t=%d adr=%02X cmd=%X spd page change status %02X\n", (INTN)t, adr, cmd, c); p = c; } if (c & 2) { break; } if (c & 4) { DBG("t=%d adr=%02X cmd=%X spd page change error!\n", (INTN)t, adr, cmd); break; } if (t > 5) { DBG("t=%d adr=%02X cmd=%X spd page change taking too long!\n", (INTN)t, adr, cmd); break; // break after 5ms } } return smb_read_byte(base, adr, cmd); } IoWrite8(base + SMBHSTSTS, 0xBF); IoWrite8(base + SMBHSTADD, (adr << 1) | 1); // read from spd IoWrite8(base + SMBHSTCMD, (UINT8)(cmd & 0xFF)); // SMBus uses 8 bit commands IoWrite8(base + SMBHSTCNT, 0x48); // Start + Byte Data Read // status goes from 0x41 (Busy) -> 0x42 (Completed) or 0x44 (Error) p = 0xFF; t1 = AsmReadTsc(); while (1) { // wait until command finished c = IoRead8(base + SMBHSTSTS); t2 = AsmReadTsc(); t = DivU64x64Remainder(MultU64x32(t2 - t1, 1000), gCPUStructure.TSCFrequency, NULL); if (c != p) { DBG("t=%d adr=%02X cmd=%X spd read status %02X\n", (INTN)t, adr, cmd, c); p = c; } if (c & 2) { break; } /* if (c & 4) { // This alway happens when trying to read the memory type (cmd 2) of an empty slot DBG("t=%d adr=%02X cmd=%X spd byte read error!\n", (INTN)t, adr, cmd); break; } */ if (t > 200) { // if (cmd != 2) DBG("t=%d adr=%02X cmd=%X spd byte read taking too long!\n", (INTN)t, adr, cmd); IoWrite8(base + SMBHSTCNT, IoRead8(base + SMBHSTCNT) | 2); return 0xFF; // break after 5ms } } return IoRead8(base + SMBHSTDAT); } else { IoWrite8(base + SMBHSTSTS_NV, 0x1f); // reset SMBus Controller IoWrite8(base + SMBHSTDAT_NV, 0xff); t1 = AsmReadTsc(); //rdtsc(l1, h1); while ( IoRead8(base + SMBHSTSTS_NV) & 0x01) { // wait until read t2 = AsmReadTsc(); //rdtsc(l2, h2); t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0); if (t > 5) return 0xFF; // break } IoWrite8(base + SMBHSTSTS_NV, 0x00); // clear status register IoWrite16(base + SMBHSTCMD_NV, cmd); IoWrite8(base + SMBHSTADD_NV, (adr << 1) | 0x01 ); IoWrite8(base + SMBHPRTCL_NV, 0x07 ); t1 = AsmReadTsc(); while (!( IoRead8(base + SMBHSTSTS_NV) & 0x9F)) { // wait till command finished t2 = AsmReadTsc(); t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0); if (t > 5) break; // break after 5ms } return IoRead8(base + SMBHSTDAT_NV); } } 1 Link to comment Share on other sites More sharing options...
dgsga Posted May 19, 2016 Share Posted May 19, 2016 The choices are documented at http://www.tutorialspoint.com/svn/svn_resolve_conflicts.htm I would choose TC or TF if I know I didn't change that file. But before that I would go to the Finder and duplicate the Clover folder and manually compare after the update is complete to make sure something weird didn't happen and to see what everyone else was changing. The divide by 1000 is for converting Hz to kHz so that t is milliseconds instead of seconds. It would be faster and more accurate to multiply cycles by 1000 instead. Changing (t > 5) to (t > 200) would be the best way to increase the time out. I would replace the smb_read_byte routine with the following test version to see how the status changes (the long timeout will increase Clover startup time by several seconds so use this only for checking the behavior of the SMBus spd read routine): @joevt, Here's the output from your revised code. I've tried increasing the timeout further but still the same result, status appears to be read error. Could it be that the device is always busy so can't be read? 0:123 0:000 ScanSPD() start 0:124 0:000 SMBus device : 8086 8D22 class=0C0500 status=Success 0:124 0:000 SMBus CmdReg: 0x1 0:124 0:000 Scanning SMBus [8086:8D22], mmio: 0xFB135004, ioport: 0x580, hostc: 0x1 0:124 0:000 Slots to scan [8]... 0:124 0:000 t=0 adr=50 cmd=2 host busy status 00 0:124 0:000 t=0 adr=50 cmd=2 host busy status 40 0:364 0:240 t=0 adr=50 cmd=2 spd read status 41 0:365 0:000 t=0 adr=50 cmd=2 spd read status 44 0:525 0:160 t=201 adr=50 cmd=2 spd byte read taking too long! 0:525 0:000 t=0 adr=51 cmd=2 host busy status 00 0:525 0:000 t=0 adr=51 cmd=2 host busy status 40 0:766 0:240 t=0 adr=51 cmd=2 spd read status 41 0:766 0:000 t=0 adr=51 cmd=2 spd read status 45 0:766 0:000 t=0 adr=51 cmd=2 spd read status 44 0:927 0:160 t=201 adr=51 cmd=2 spd byte read taking too long! 0:927 0:000 t=0 adr=52 cmd=2 host busy status 00 0:927 0:000 t=0 adr=52 cmd=2 host busy status 40 1:168 0:240 t=0 adr=52 cmd=2 spd read status 41 1:168 0:000 t=0 adr=52 cmd=2 spd read status 44 1:328 0:160 t=201 adr=52 cmd=2 spd byte read taking too long! 1:328 0:000 t=0 adr=53 cmd=2 host busy status 00 1:328 0:000 t=0 adr=53 cmd=2 host busy status 40 1:569 0:240 t=0 adr=53 cmd=2 spd read status 41 1:569 0:000 t=0 adr=53 cmd=2 spd read status 44 1:730 0:160 t=201 adr=53 cmd=2 spd byte read taking too long! 1:730 0:000 t=0 adr=54 cmd=2 host busy status 00 1:730 0:000 t=0 adr=54 cmd=2 host busy status 40 1:971 0:240 t=0 adr=54 cmd=2 spd read status 41 1:971 0:000 t=0 adr=54 cmd=2 spd read status 44 2:132 0:160 t=201 adr=54 cmd=2 spd byte read taking too long! 2:132 0:000 t=0 adr=55 cmd=2 host busy status 00 2:132 0:000 t=0 adr=55 cmd=2 host busy status 40 2:372 0:240 t=0 adr=55 cmd=2 spd read status 41 2:373 0:000 t=0 adr=55 cmd=2 spd read status 44 2:533 0:160 t=201 adr=55 cmd=2 spd byte read taking too long! 2:533 0:000 t=0 adr=56 cmd=2 host busy status 00 2:533 0:000 t=0 adr=56 cmd=2 host busy status 40 2:774 0:240 t=0 adr=56 cmd=2 spd read status 41 2:774 0:000 t=0 adr=56 cmd=2 spd read status 44 2:935 0:160 t=201 adr=56 cmd=2 spd byte read taking too long! 2:935 0:000 t=0 adr=57 cmd=2 host busy status 00 2:935 0:000 t=0 adr=57 cmd=2 host busy status 40 3:176 0:240 t=0 adr=57 cmd=2 spd read status 41 3:176 0:000 t=0 adr=57 cmd=2 spd read status 44 3:336 0:160 t=201 adr=57 cmd=2 spd byte read taking too long! 3:336 0:000 ScanSPD() end Link to comment Share on other sites More sharing options...
joevt Posted May 20, 2016 Share Posted May 20, 2016 @joevt, Here's the output from your revised code. I've tried increasing the timeout further but still the same result, status appears to be read error. Could it be that the device is always busy so can't be read? 0:123 0:000 ScanSPD() start 0:124 0:000 SMBus device : 8086 8D22 class=0C0500 status=Success 0:124 0:000 SMBus CmdReg: 0x1 0:124 0:000 Scanning SMBus [8086:8D22], mmio: 0xFB135004, ioport: 0x580, hostc: 0x1 0:124 0:000 Slots to scan [8]... 0:124 0:000 t=0 adr=50 cmd=2 host busy status 00 0:124 0:000 t=0 adr=50 cmd=2 host busy status 40 0:364 0:240 t=0 adr=50 cmd=2 spd read status 41 0:365 0:000 t=0 adr=50 cmd=2 spd read status 44 0:525 0:160 t=201 adr=50 cmd=2 spd byte read taking too long! 0:525 0:000 t=0 adr=51 cmd=2 host busy status 00 0:525 0:000 t=0 adr=51 cmd=2 host busy status 40 0:766 0:240 t=0 adr=51 cmd=2 spd read status 41 0:766 0:000 t=0 adr=51 cmd=2 spd read status 45 0:766 0:000 t=0 adr=51 cmd=2 spd read status 44 0:927 0:160 t=201 adr=51 cmd=2 spd byte read taking too long! 0:927 0:000 t=0 adr=52 cmd=2 host busy status 00 0:927 0:000 t=0 adr=52 cmd=2 host busy status 40 1:168 0:240 t=0 adr=52 cmd=2 spd read status 41 1:168 0:000 t=0 adr=52 cmd=2 spd read status 44 1:328 0:160 t=201 adr=52 cmd=2 spd byte read taking too long! ... 3:336 0:000 ScanSPD() end Those look like status bytes that you would expect from the SMBus when no device is connected at the adr. The first mystery is why it doesn't see a device in your machine so the status byte should start as 0x41 then change to 0x42 instead of 0x44. I'm not sure that the host busy check is working correctly. Yours is the same as mine but it seems to be different than what my SBUS DSDT methods expect. I'll add comments about that in the next test. It's strange that t=0 twice in a row. I'll change the output to use microseconds in the next test so we can see the change in time. The read is reporting an error (status & 0x4) but I wonder if there is a valid byte in the DAT register at that time, so I'll add that to the output in the next test. Here's a new testing replacement for smb_read_byte. I've moved the wait loop into a new function. Change DEBUGSPD to 0 to get a non-test version that will not wait for timeout, and will not spam output to the log. #define DEBUGSPD 1 const CHAR8* SMBHOST = "host busy"; const CHAR8* SPDPAGE = "spd page change"; const CHAR8* SPDREAD = "spd read"; UINT8 smb_wait_transaction_complete(UINT32 base, UINT8 adr, UINT16 cmd, INTN timeout_us, const CHAR8* process) { UINT8 c; UINT8 p; UINT64 t, t1, t2; p = 0xFF; t1 = AsmReadTsc(); //rdtsc(l1, h1); if (smbIntel) { while (1) { // wait until command finished c = IoRead8(base + SMBHSTSTS); t2 = AsmReadTsc(); //rdtsc(l2, h2); t = DivU64x64Remainder(MultU64x32(t2 - t1, 1000000), gCPUStructure.TSCFrequency, NULL); #if DEBUGSPD if (c != p) { DBG("t=%d adr=%02X cmd=%X %a status %02X\n", t, adr, cmd, process, c); p = c; } #endif // This must be wrong - bit 0 always appears to start as 0? if (process == SMBHOST && ~c & 1) { // the SMBHOST process isn't a control command so don't expect the host status to return a control command result (status & 0x1E != 0) // but it doesn't seem to return any result - the status will goes quickly from 0x00 to 0x40 (I don't know what the means) and remains at 0x40. // My DSDT says an SMBus control call is supposed to wait for status & 0x40 == 0, then wait for status & 0x01 == 0 which is almost the reverse of what we're seeing. #if DEBUGSPD // if we're debugging, then let the first one timeout, to see if the status changes if (cmd != 2) #endif break; } if (c & 2) { break; } if (c & 4) { if (process != SPDREAD) { // This alway happens when trying to read the memory type (cmd 2) of an empty slot so don't report the error DBG("t=%d adr=%02X cmd=%X %a error!\n", t, adr, cmd, process); } #if !DEBUGSPD break; #endif } if (t > timeout_us) { if (process == SMBHOST && ~c & 1) { // for SMBHOST, we don't know there's an error. break; } DBG("t=%d adr=%02X cmd=%X %a (%02X) timeout!\n", t, adr, cmd, process, IoRead8(base + SMBHSTDAT)); return FALSE; // fail, stop! } } } else { t1 = AsmReadTsc(); //rdtsc(l1, h1); while (1) { c = IoRead8(base + SMBHSTSTS_NV); if (process == SMBHOST) { if (~c && 1) { // wait until read return TRUE; } } else { if (c & 0x9F) { // wait till command finished return TRUE; } } t2 = AsmReadTsc(); //rdtsc(l2, h2); t = DivU64x64Remainder(MultU64x32(t2 - t1, 1000000), gCPUStructure.TSCFrequency, NULL); if (t > timeout_us) { if (process == SMBHOST) { return FALSE; } break; } } } return TRUE; // success, keep going! } UINT8 smb_read_byte(UINT32 base, UINT8 adr, UINT16 cmd) { UINT8 page = (cmd >> 8) & 1; if (smbIntel) { // IoWrite8(base + SMBHSTSTS, 0xFF); // reset SMBus Controller (set busy) smb_wait_transaction_complete(base, adr, cmd, 300000, SMBHOST); if (page != smbPage) { //IoWrite8(base + SMBHSTCMD, 0x00); IoWrite8(base + SMBHSTADD, 0x6C + (page << 1)); // Set SPD Page Address IoWrite8(base + SMBHSTCNT, 0x40); // Start + Quick Write ; don't use 0x48 because that gets status 0x44 (Error) // status goes from 0x41 (Busy) -> 0x42 (Completed) smbPage = page; smb_wait_transaction_complete(base, adr, cmd, 5000, SPDPAGE); IoWrite8(base + SMBHSTSTS, 0xFF); // reset SMBus Controller (set busy) return smb_read_byte(base, adr, cmd); } IoWrite8(base + SMBHSTSTS, 0xBF); IoWrite8(base + SMBHSTDAT, 0xFF); IoWrite8(base + SMBHSTADD, (adr << 1) | 0x01); // read from spd IoWrite8(base + SMBHSTCMD, (UINT8)(cmd & 0xFF)); // SMBus uses 8 bit commands IoWrite8(base + SMBHSTCNT, 0x48); // Start + Byte Data Read // status goes from 0x41 (Busy) -> 0x42 (Completed) or 0x44 (Error) if (smb_wait_transaction_complete(base, adr, cmd, 200000, SPDREAD)) { IoWrite8(base + SMBHSTSTS, 0xFF); // reset SMBus Controller (set busy) return IoRead8(base + SMBHSTDAT); } else { IoWrite8(base + SMBHSTCNT, IoRead8(base + SMBHSTCNT) | 2); // kill IoWrite8(base + SMBHSTSTS, 0xFF); // reset SMBus Controller (set busy) } return 0xFF; } else { IoWrite8(base + SMBHSTSTS_NV, 0x1F); // reset SMBus Controller IoWrite8(base + SMBHSTDAT_NV, 0xFF); if (!smb_wait_transaction_complete(base, adr, cmd, 5000, SMBHOST)) return 0xFF; IoWrite8(base + SMBHSTSTS_NV, 0x00); // clear status register IoWrite16(base + SMBHSTCMD_NV, cmd); IoWrite8(base + SMBHSTADD_NV, (adr << 1) | 0x01); // read from spd IoWrite8(base + SMBHPRTCL_NV, 0x07); smb_wait_transaction_complete(base, adr, cmd, 5000, SPDREAD); return IoRead8(base + SMBHSTDAT_NV); } } I wonder if it's possible to get a copy of the BIOS, disassemble it, and see how it populates the SMBIOS type 17 table? The ASUS website has firmware files in .cap format but I don't know anything about that. Finding the correct piece of code seems like searching for a needle in a haystack so I won't try that. I am able to extract the DSDT using the following commands (which isn't useful unless you don't have a computer with the firmware that you want to look at): thecap=~/Downloads/X99-A-ASUS-3101.CAP # Find possible DSDT aml header strings -a -t d ${thecap} | grep DSDT 5423524 DSDTv_ 7949521 _DSDT # Check each result dd if=${thecap} of=/tmp/dsdt.aml bs=1 skip=$((5423524)) count=0x24 2> /dev/null xxd < /tmp/dsdt.aml 0000000: 4453 4454 765f 0300 02e4 414c 4153 4b41 DSDTv_....ALASKA 0000010: 4120 4d20 4920 0000 0920 0701 494e 544c A M I ... ..INTL 0000020: 1309 1220 ... # That looks like an aml header. Get the size of the DSDT and dump those bytes to an aml file. dd if=${thecap} of=/tmp/dsdt.aml bs=1 skip=$((5423524+4)) count=4 2> /dev/null dsdtsize=$(rev < /tmp/dsdt.aml | xxd -p) dsdtsize=$((0x${dsdtsize:1:8})) dd if=${thecap} of=/tmp/dsdt.aml bs=1 skip=5423524 count=${dsdtsize} 2> /dev/null # Open the file in MaciASL.app open /tmp/dsdt.aml xxd < ${thecap} > /tmp/cap.txt I wonder if the SMBus has devices on different addresses besides the ones we're looking at (50-57). Run Thaiphoon Burner and take a screenshot of the SMBus menu after doing a "Search for SMB Devices". You may need to set the delay option if you're using Snipping Tool. Mine looks like the attached image. Link to comment Share on other sites More sharing options...
dgsga Posted May 20, 2016 Share Posted May 20, 2016 @joevt Thanks for working on this! Attached is a screenshot from Thaiphoon plus output of revised code plus native DSDT extracted from bios: 0:124 0:000 ScanSPD() start 0:124 0:000 SMBus device : 8086 8D22 class=0C0500 status=Success 0:124 0:000 SMBus CmdReg: 0x1 0:124 0:000 Scanning SMBus [8086:8D22], mmio: 0xFB135004, ioport: 0x580, hostc: 0x1 0:124 0:000 Slots to scan [8]... 0:124 0:000 t=1 adr=50 cmd=2 host busy status 00 0:124 0:000 t=4 adr=50 cmd=2 host busy status 40 0:424 0:300 t=1 adr=50 cmd=2 spd read status 41 0:424 0:000 t=118 adr=50 cmd=2 spd read status 44 0:624 0:199 t=200002 adr=50 cmd=2 spd read (FF) timeout! 0:624 0:000 t=1 adr=51 cmd=2 host busy status 00 0:624 0:000 t=3 adr=51 cmd=2 host busy status 40 0:924 0:300 t=1 adr=51 cmd=2 spd read status 41 0:924 0:000 t=118 adr=51 cmd=2 spd read status 44 1:124 0:199 t=200002 adr=51 cmd=2 spd read (FF) timeout! 1:124 0:000 t=1 adr=52 cmd=2 host busy status 00 1:124 0:000 t=3 adr=52 cmd=2 host busy status 40 1:424 0:300 t=1 adr=52 cmd=2 spd read status 41 1:424 0:000 t=117 adr=52 cmd=2 spd read status 44 1:624 0:199 t=200002 adr=52 cmd=2 spd read (FF) timeout! 1:624 0:000 t=1 adr=53 cmd=2 host busy status 00 1:624 0:000 t=3 adr=53 cmd=2 host busy status 40 1:924 0:300 t=1 adr=53 cmd=2 spd read status 41 1:924 0:000 t=117 adr=53 cmd=2 spd read status 44 2:124 0:199 t=200002 adr=53 cmd=2 spd read (FF) timeout! 2:124 0:000 t=1 adr=54 cmd=2 host busy status 00 2:124 0:000 t=3 adr=54 cmd=2 host busy status 40 2:424 0:300 t=1 adr=54 cmd=2 spd read status 41 2:424 0:000 t=119 adr=54 cmd=2 spd read status 44 2:624 0:199 t=200002 adr=54 cmd=2 spd read (FF) timeout! 2:624 0:000 t=1 adr=55 cmd=2 host busy status 00 2:624 0:000 t=3 adr=55 cmd=2 host busy status 40 2:924 0:300 t=1 adr=55 cmd=2 spd read status 41 2:924 0:000 t=119 adr=55 cmd=2 spd read status 44 3:124 0:199 t=200001 adr=55 cmd=2 spd read (FF) timeout! 3:124 0:000 t=1 adr=56 cmd=2 host busy status 00 3:124 0:000 t=3 adr=56 cmd=2 host busy status 40 3:424 0:300 t=1 adr=56 cmd=2 spd read status 41 3:424 0:000 t=118 adr=56 cmd=2 spd read status 44 3:624 0:199 t=200001 adr=56 cmd=2 spd read (FF) timeout! 3:624 0:000 t=1 adr=57 cmd=2 host busy status 00 3:624 0:000 t=3 adr=57 cmd=2 host busy status 40 3:924 0:300 t=1 adr=57 cmd=2 spd read status 41 3:924 0:000 t=117 adr=57 cmd=2 spd read status 44 4:124 0:199 t=200001 adr=57 cmd=2 spd read (FF) timeout! 4:124 0:000 ScanSPD() end DSDT.dsl.zip Link to comment Share on other sites More sharing options...
joevt Posted May 20, 2016 Share Posted May 20, 2016 @joevt Thanks for working on this! Attached is a screenshot from Thaiphoon plus output of revised code plus native DSDT extracted from bios: 0:124 0:000 ScanSPD() start 0:124 0:000 SMBus device : 8086 8D22 class=0C0500 status=Success 0:124 0:000 SMBus CmdReg: 0x1 0:124 0:000 Scanning SMBus [8086:8D22], mmio: 0xFB135004, ioport: 0x580, hostc: 0x1 0:124 0:000 Slots to scan [8]... 0:124 0:000 t=1 adr=50 cmd=2 host busy status 00 0:124 0:000 t=4 adr=50 cmd=2 host busy status 40 0:424 0:300 t=1 adr=50 cmd=2 spd read status 41 0:424 0:000 t=118 adr=50 cmd=2 spd read status 44 0:624 0:199 t=200002 adr=50 cmd=2 spd read (FF) timeout! ... 3:624 0:000 t=1 adr=57 cmd=2 host busy status 00 3:624 0:000 t=3 adr=57 cmd=2 host busy status 40 3:924 0:300 t=1 adr=57 cmd=2 spd read status 41 3:924 0:000 t=117 adr=57 cmd=2 spd read status 44 4:124 0:199 t=200001 adr=57 cmd=2 spd read (FF) timeout! 4:124 0:000 ScanSPD() end Nothing unexpected in that new output. After reading the "Intel® C610 Series Chipset and Intel® X99 Chipset Platform Controller Hub (PCH) Datasheet", I now understand why status starts at 00 and immediately goes to 40. 00 means the host is not in use. Reading that value makes the host in use by us. We relinquish ownership when we write FF to the status. That clears the in-use flag and some other stuff. The screenshot is interesting. Yours says SMBus#1 while mine says SMBus#0. Did Thaiphoon Burner say anything about reading the buses? Can you send a screen shot of the entire menu? If there are other buses, then I would like to know what SMBus addresses are used on each bus. I think the next step is to create an SMBus scanner to find devices, then we can compare the results with the Thaiphoon Burner result. That could confirm that we're reading the wrong bus. The datasheet mentions 3 other buses, MS SMBus0,1,2 that are usually hidden. I don't know how to access those. They are hidden by the SPSR (device 17, function 0 (0x11:0) and would be function 1,2,3 of device 17 (0x11:1,0x11:2,0x11:3). There may be other things affecting that such as TCO and EVA. I'm not sure. 4 Link to comment Share on other sites More sharing options...
cecekpawon Posted May 21, 2016 Share Posted May 21, 2016 hexdump -n32 -C Mac-F60DEB81FF30ACF6.smc 00000000 23 20 56 65 72 73 69 6f 6e 3a 20 32 2e 32 30 66 |# Version: 2.20f| 00000010 31 38 0a 48 3a 32 30 3a 38 35 30 30 30 30 30 30 |18.H:20:85000000| 2 Link to comment Share on other sites More sharing options...
dgsga Posted May 22, 2016 Share Posted May 22, 2016 Nothing unexpected in that new output. After reading the "Intel® C610 Series Chipset and Intel® X99 Chipset Platform Controller Hub (PCH) Datasheet", I now understand why status starts at 00 and immediately goes to 40. 00 means the host is not in use. Reading that value makes the host in use by us. We relinquish ownership when we write FF to the status. That clears the in-use flag and some other stuff. The screenshot is interesting. Yours says SMBus#1 while mine says SMBus#0. Did Thaiphoon Burner say anything about reading the buses? Can you send a screen shot of the entire menu? If there are other buses, then I would like to know what SMBus addresses are used on each bus. I think the next step is to create an SMBus scanner to find devices, then we can compare the results with the Thaiphoon Burner result. That could confirm that we're reading the wrong bus. The datasheet mentions 3 other buses, MS SMBus0,1,2 that are usually hidden. I don't know how to access those. They are hidden by the SPSR (device 17, function 0 (0x11:0) and would be function 1,2,3 of device 17 (0x11:1,0x11:2,0x11:3). There may be other things affecting that such as TCO and EVA. I'm not sure. Think we might be getting somewhere, looks like Clover might be looking in the wrong place for SPD on X99 chipsets. Thaiphoon shows there is indeed an SMBus#0 at 44h marked as an unknown device. When you scan it it comes up with nothing. Could the code be looking there by default and so not find anything? I have also noticed that in my ioreg the IODeviceMemory address for SBUS is 0xfb135000, whereas the boot log shows mmio as 0xfb135004... Link to comment Share on other sites More sharing options...
joevt Posted May 22, 2016 Share Posted May 22, 2016 Think we might be getting somewhere, looks like Clover might be looking in the wrong place for SPD on X99 chipsets. Thaiphoon shows there is indeed an SMBus#0 at 44h marked as an unknown device. When you scan it it comes up with nothing. Could the code be looking there by default and so not find anything? I have also noticed that in my ioreg the IODeviceMemory address for SBUS is 0xfb135000, whereas the boot log shows mmio as 0xfb135004... I'm adding a couple other methods for finding/accessing SMBus devices. Maybe one of them will work. I've also added an SMBus scanner to get a list of slaves on an SMBus. Bit 0-7 of mmio are not part of the address and Clover uses the ioport address instead of that memory mapped address anyway. Link to comment Share on other sites More sharing options...
Recommended Posts