andreiw / RaspberryPiPkg

DEPRECATED - DO NOT USE | Go here instead ->
https://github.com/tianocore/edk2-platforms/tree/master/Platform/RaspberryPi/RPi3
746 stars 143 forks source link

MsftFunctionConfig exposed from vendor long seems not fully compatible with Windows 10 #96

Closed driver1998 closed 5 years ago

driver1998 commented 5 years ago

First issue of 2019 ;).

I am trying to build my USB HID - I2C adapter for RPi-WoA using Arduino, as a workaround of the currently broken USB driver. But the I2C bus is not working, if you try to run i2cdetect from my rpi3win10demo repo, it will timeout at all slave addresses and report no devices hook up to the bus, even when you do have some. SPI and GPIO works though. When I change from vender long MsftFunctionConfig to official MsftFunctionConfig code and compile it with Microsoft's asl, everything is working fine... So that should be some issue around here.

andreiw commented 5 years ago

Interesting, because it ought to be equivalent.

To be investigated...

driver1998 commented 5 years ago

I compiled both the offical MsftFunctionConfig code and the VendorLong one using Microsoft's asl.exe, and the output is the same. So it might be iasl's fault?

andreiw commented 5 years ago

What about the DSDT header? I bet we need to make the header report the MSFT ASL compiler id and revision?

A

16 янв. 2019 г., в 7:30, driver1998 notifications@github.com написал(а):

I compiled both the offical MsftFunctionConfig code and the VendorLong one using Microsoft's asl.exe, and the output is the same. So it might be iasl's fault?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

driver1998 commented 5 years ago

Yeah, I can confirm that DSDT header is the issue. I wrote a python(2) script to hex edit the compiled aml file, change the compiler id and revision to MSFT 5.0.0, (I recalculated checksum, of course), and it worked. The problem is, how to incorporate this script into the build process....

#!/usr/bin/env python

import io

def write_bytes(fd, offset, data):
    fd.seek(offset)
    fd.write(data)

def calculate_checksum(fd):
    write_bytes(fd, 9, "\x00")

    length = fd.seek(0, 2)
    fd.seek(0)
    b = fd.read(length)

    checksum = 0
    for i in b:
        checksum = (checksum - ord(i)) % 256

    write_bytes(fd, 9, chr(checksum))

with io.open('DSDT.aml', mode="rb+") as fd:
    # Compiler ID = MSFT
    write_bytes(fd, 28, "MSFT")
    # Compiler Revision = 5.0
    write_bytes(fd, 32, "\x00\x00\x00\x05")
    # Recalculate checksum
    calculate_checksum(fd)

I have tested I2C only yet, but SPI and GPIO are likely working as well (they don't seem to be affected by this issue).

andreiw commented 5 years ago

Thanks, there might be an easier way, I’ll look

A

17 янв. 2019 г., в 5:43, driver1998 notifications@github.com написал(а):

Yeah, I can confirm that DSDT header is the issue. I wrote a python script to hex edit the compiled aml file, change the compiler id and revision to MSFT 5.0.0, (I recalculated checksum, of course), and it worked. The problem is, how to incorporate this script into the build process....

!/usr/bin/env python

import io

def write_bytes(fd, offset, data): fd.seek(offset) fd.write(data)

def calculate_checksum(fd): write_bytes(fd, 9, "\x00")

length = fd.seek(0, 2)
fd.seek(0)
b = fd.read(length)

checksum = 0
for i in b:
    checksum = (checksum - ord(i)) % 256

write_bytes(fd, 9, chr(checksum))

with io.open('DSDT.aml', mode="rb+") as fd:

Compiler ID = MSFT

write_bytes(fd, 28, "MSFT")
# Compiler Revision = 5.0
write_bytes(fd, 32, "\x00\x00\x00\x05")
# Recalculate checksum
calculate_checksum(fd)

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

driver1998 commented 5 years ago

I found something even more interesting. First, I compile DSDT.asl with iasl, nothing fancy, iasl DSDT.asl. Then I decompile it back with iasl -d DSDT.asl, the vendorlong MsftFunctionConfig is unchanged, which is as expected. But when I build the whole UEFI using build5 script and decompile the compiled DSDT.aml in Build directory, I found that it missed a few bytes. WTF!?

The vendorlong MsftFunctionConfig of I2C1, decompiled from my manual compilation.

                    VendorLong  ()      // Length = 0x31
                    {
                        /* 0000 */  0x00, 0x60, 0x44, 0xD5, 0xF3, 0x1F, 0x11, 0x60,  // .`D....`
                        /* 0008 */  0x4A, 0xB8, 0xB0, 0x9C, 0x2D, 0x23, 0x30, 0xDD,  // J...-#0.
                        /* 0010 */  0x2F, 0x8D, 0x1D, 0x00, 0x01, 0x10, 0x00, 0x01,  // /.......
                        /* 0018 */  0x04, 0x00, 0x12, 0x00, 0x00, 0x16, 0x00, 0x20,  // ....... 
                        /* 0020 */  0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x5C,  // .......\
                        /* 0028 */  0x5F, 0x53, 0x42, 0x2E, 0x47, 0x50, 0x49, 0x30,  // _SB.GPI0
                        /* 0030 */  0x00                                             // .
                    }

And the same thing from the DSDT.aml get from the UEFI build.

                    VendorLong  ()      // Length = 0x29
                    {
                        /* 0000 */  0x00, 0x60, 0x44, 0xD5, 0xF3, 0x1F, 0x11, 0x60,  // .`D....`
                        /* 0008 */  0x4A, 0xB8, 0xB0, 0x9C, 0x2D, 0x23, 0x30, 0xDD,  // J...-#0.
                        /* 0010 */  0x2F, 0x8D, 0x1D, 0x00, 0x01, 0x10, 0x00, 0x01,  // /.......
                        /* 0018 */  0x04, 0x00, 0x12, 0x00, 0x00, 0x16, 0x00, 0x20,  // ....... 
                        /* 0020 */  0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x5C,  // .......\
                        /* 0028 */  0x00                                             // .
                    }

There must be some dumb "optimization" going on that screws the output... this happens from both DEBUG and RELEASE build.

My build environment: Ubuntu 18.04 @ WSL iasl Version 20180105 from Ubuntu gcc-linaro-5.5.0-2017.10-x86_64_aarch64-linux-gnu toolchain

driver1998 commented 5 years ago

It seems that the DSDT header is not the problem, once I sorted the problem that I2C1's MsftFunctionConfig is corrupted, I2C is working, along with SPI and GPIO.

No need for hacking the compiler ID and revision.

driver1998 commented 5 years ago

I created a post build script that recompiles DSDT and rebuilds FD image with the newly compiled file... There must be some better way to do that. (It is a compiler config issue, isn't it?)

andreiw commented 5 years ago

Yeah I’ll need to figure it out. Thanks for your exploration. Need to figure out why running iasl manually is different.

A

17 янв. 2019 г., в 11:29, driver1998 notifications@github.com написал(а):

I created a post build script that recompiles DSDT and rebuilds FD image with the newly compiled file... There must be some better way to do that. (It is a compiler config issue, isn't it?)

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

andreiw commented 5 years ago

🤦‍♂️Yeah.

Emacs was being confused by open “ in these comments too, so I had escaped them with a backslash. Should have occured to me to sanitize hanging backslashes as well.

Thanks again.