-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OcMainLib: Read and set serial PCD values from config #330
Conversation
@joevt I think now everything is nearly complete. Could you please test it? Or, feel free to leave more comments here. :) |
I an working on testing. |
I haven't noticed a change in serial output yet. I'll add some debug statements to see if it's accessing the PCIe card. |
Thanks for testing. I am away from keyboard right now, so could you please try adding some debug prints and see if the keys are successfully overridden? Or, will there be more things to handle, including booter/XNU patches? |
\texttt{PciDeviceInfo}\\ | ||
\textbf{Type}: \texttt{plist\ data}\\ | ||
\textbf{Failsafe}: \texttt{0xFF}\\ | ||
\textbf{Description}: Set PCI serial device information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joevt Would you please provide more information on how to convert a device path to the formatted PciDeviceInfo bytes? Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My current theory is that I just need the device number and function number from each PCI device in the UEFI device path for the first two bytes of each node in the PciDeviceInfo path. The second two bytes I'll leave as 00 00. The last node is followed by an FF.
The following code find PCIe serial ports and outputs their paths.
ioreg -p IODeviceTree -lw0 | perl -e '
$ioregpath=""; $pcipath=""; while (<>) {
if ( /^([ |]*)\+\-o (.+) <class (\w+)/ ) {
$indent = (length $1) / 2; $name = $2; $class = $3;
$ioregpath =~ s|^((/[^/]*){$indent}).*|$1/$name|;
$pcipath =~ s|^((/[^/]*){$indent}).*|$1/|;
$name = ""; $uid = 0; $classcode = "";
}
if ( $class eq "IOACPIPlatformDevice" ) { if ( /^[ |]*"name" = <"([^\"]*)">/ ) { $name = $1; }; if ( /^[ |]*"_UID" = "(\d+)"/ ) { $uid = $1; } }
elsif ( $class eq "IOPCIDevice" ) { if ( /^[ |]*"pcidebug" = "\d+:(\d+):(\d+).*"/ ) { $name = sprintf("Pci(0x%x,0x%x)", $1, $2); } if ( /^[ |]*"class-code" = <(\w+)>/ ) { $classcode = $1; } }
if ( /^[ |]*}/ && $name ) {
if ( $class eq "IOACPIPlatformDevice" ) {
if ($name eq "PNP0A03") { $name = sprintf ("PciRoot(0x%x)", $uid); }
elsif ($name eq "PNP0A08") { $name = sprintf ("PciRoot(0x%x)", $uid); }
elsif ($name =~ /PNP..../) { $name = sprintf ("Acpi(%s,0x%x)", $name, $uid); }
# not translating all ACPI types since we only care about PCI devices
}
$pcipath .= $name;
if ( $classcode eq "02000700" ) {
$serialdevicepath = $pcipath =~ s/.*PciRoot\(0x0\)//r =~ s|/Pci\(||gr =~ s|\)| 00 00 |gr =~ s|0x||gr =~ s|,| |gr =~ s|\b(\w)\b|0\1|gr =~ s|$|FF|r;
print $ioregpath =~ s|/Root/||r . "\n";
print $pcipath =~ s|/*||r . "\n";
print "xxd -p -r <<< \"" . $serialdevicepath . "\" | base64\n";
print "\n";
}
}
}
'
This is the result:
/PCI0@0/P0P9@9/P9P2@0/P2P4@1/PXS3@0
PciRoot(0x0)/Pci(0x9,0x0)/Pci(0x0,0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)
xxd -p -r <<< "09 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 FF" | base64
/PCI0@0/P0P9@9/P9P2@0/P2P4@1/PXS3@0,2
PciRoot(0x0)/Pci(0x9,0x0)/Pci(0x0,0x0)/Pci(0x1,0x0)/Pci(0x0,0x2)
xxd -p -r <<< "09 00 00 00 00 00 00 00 01 00 00 00 00 02 00 00 FF" | base64
The following can take a UEFI device path and produce the serial PciDevicePath:
serialpath=PciRoot(0x0)/Pci(0x9,0x0)/Pci(0x0,0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)
perl -pe 's/PciRoot(0x0)//;s|/Pci\(||g;s|\)| 00 00 |g;s|0x||g;s|,| |g;s|\b(\w)\b|0\1|g; s|$|FF|' <<< "$serialpath" | xxd -p -r | base64
I'll let you know when I find out if this works.
@@ -407,11 +406,39 @@ typedef enum { | |||
OC_ARRAY (OC_MISC_TOOLS_ENTRY, _, __) | |||
OC_DECLARE (OC_MISC_TOOLS_ARRAY) | |||
|
|||
/// | |||
/// Reference: | |||
/// https://github.com/acidanthera/bugtracker/issues/1954#issuecomment-1084220743 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably it is better to mention this 41-byte thing in docs, then remove these links in the comment. Same below.
I found an issue. Variable length pcd's need to be initialized with the max size that you want to support. I found this while looking at the *.i files generated by
In OpenCoreMisc.c, the line
is translated to
according to OpenCoreMisc.i. The Pcds are defined in AutoGen.c.
I couldn't find a macro in PcdLib.h that returns Anyway, with the change to |
Thanks. I committed the proper initialization at 22a852d. As for the Is it useful to change the failsafe value in OcConfigurationLib.h as well? In my opinion, no. Also, if we specify |
I don't think It is a useful tool for debugging but also for development. For example, you can open any *.i file and find any type definition very quickly and it shows which .h file that the type was defined in so you can go to it easily - especially useful if the type is defined in many similarly named *.h files. I don't think the failsafe needs to be changed. The *.dsc defines the max size, not this failsafe. PciDeviceInfo size just needs to be ≤ the max size and end with a I am continuing testing. I added some FYI, This is what I'm using for Serial for my PCIe Serial port:
|
I removed my UDK folder to get a clean checkout and recompiled. It appears to be working now. In the attached serial output capture OC serial enable true working.txt.zip, you can see that all the messages sent to console are now also sent to serial with a time stamp. I wonder if there's any messages sent to serial that are not also sent to console or vice versa? In other words, which method is best? With console redirection, it can capture output from EFI Shell and boot.efi. What benefits does serial have over console redirection? I'll do another test without console redirection to make sure it works with a more normal setup. I found some lines that only exist from console.
When OpenCore connects drivers, it makes PciSioSerialDxe.efi reinit the serial port.
So I'll disable PciSioSerialDxe.efi (which I load using Driver#### instead of OpenCore) to make sure it's not required for serial output (it's used for console redirection since my MacPro3,1 doesn't come with a serial driver). In my previous comment posted earlier today, you see that I didn't have standard whitespace in my plist (the value follows |
I think this is my final test. This time I'm not using PciSioSerialDxe.efi and console redirection to serial port. Console is set to display only. One good thing is that the console output to my 2560x1600 display is no longer reduced to 80x25 characters (as I described in acidanthera/bugtracker#1954 ) As you can see in the attached output, my xnu patch to have serial output go to the PCIe serial port still works (xnu output starts at I guess the only thing missing from this serial setup would be output from EFI Shell or any drivers that might output to console. |
Thanks again for testing. Shall we integrate the UPDATE - #331 |
Which IOPCIFamily patch? We've done everything we need to do for Serial in OpenCore. The rest of the issues/questions in acidanthera/bugtracker#1954 are mostly related to console redirection in EFI or serial output from macOS. |
@joevt looks good to me, shall we merge this? |
Yes. |
Done. |
closes acidanthera/bugtracker#1954
TODO:
After merging: