Date: Sat, 8 Dec 2018 18:52:01 +0100 (CET) From: <byuu@tutanota.com> To: <freebsd-hackers@freebsd.org> Subject: I'd like to submit a kernel patch for a new sysctl to use EFI instead of ACPI for poweroff + reboot Message-ID: <LTDwcvo--3-1@tutanota.com>
next in thread | raw e-mail | index | archive | help
Hello, first time poster here, please go easy on me ^-^; I would like to submit a patch for inclusion to the FreeBSD kernel, but wan= t to first see if there is a chance it will be accepted before writing it o= r not. Currently, /usr/src/sys/dev/efidev/efirt.c contains the efi_reset_system() = function, which calls EFI_RESET_WARM. It's exposed in /usr/src/sys/sys/efi.= h I would like to add efi_poweroff_system() to efirt.c, which is identical to= efi_reset_system(), but with EFI_RESET_SHUTDOWN as arg1, which we have to = add as an enum item to efi.h as well (its value is 2, so it would go direct= ly after EFI_RESET_WARM.) (These two functions are wrappers to invoke the EFI Runtime Services functi= on ResetSystem with EfiResetWarm and EfiResetShutdown. FreeBSD's loader.eli= uses them to implement its reboot and poweroff commands, for example.) Next, I would like to add a patch to /usr/src/sys/dev/acpica/acpi.c to acpi= _shutdown_final to check a new kernel sysctl, not picky about the name, but= something like "hw.acpi.efi_shutdown=3D0", which can be optionally changed= to 1 by the users. It could be changed at run-time with no ill effect. When this option is set to 1, and efi_systbl_phys is not NULL (eg we are ru= nning on an EFI system), I would like to invoke efi_poweroff_system() inste= ad of AcpiEnterSleepStatePrep(ACPI_STATE_S5) This is well after all services have been halted, all disks have been detac= hed, and all USB devices have been detached. acpi_shutdown_final calls Acpi= EnterSleepStatePrep (_PTS), followed by AcpiEnterSleepState (_S5), and that= 's it. The idea is to reuse all of the shutdown handling we can. If it would be desired, I could do the same for reset events to invoke efi_= reset_system(). ... The reason I am requesting this, is because I am the owner of a Threadrippe= r 2950X with an ASRock Taichi X399M motherboard, and when I attempt to shut= down my system from FreeBSD 11.2-RELEASE or 12.0-RC3, the system hangs fore= ver and fails to power down. The call frame for this is as follows: kern_psignal(initproc, SIGUSR2); =C2=A0 kern_reboot =C2=A0 =C2=A0 shutdown_final =C2=A0 =C2=A0 =C2=A0 acpi_shutdown_final =C2=A0 =C2=A0 =C2=A0 =C2=A0 AcpiEnterSleepStatePre =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AcpiEvaluateObject =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AcpiNsEvaluate =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AcpiPsExecuteMethod =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AcpiPsParseAml =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AcpiPsParseL= oop=C2=A0 //from this point on, it likely varies per DSDT =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 WalkS= tate->AscendingCallback =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 AcpiDsExecEndOp =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 AcpiGbl_OpTypeDispatch[OpType] =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 AcpiExOpcode_1A_0T_0R =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 AcpiExSystemDoSleep =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AcpiOsSleep =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pause("acpislp", 300) (eg tsleep) I do not know why, but the call to pause never returns. I have tried over a= dozen things to find a fix for this: analyzing my DSDT ASL code via acpidu= mp, disabling SMT + all cores, wrapping pause in a critical section, trying= SLEEP instead of pause, trying a spinloop instead of pause, trying to skip= the AcpiEnterSleepStatePrep call, building a kernel with options ACPI_DEBU= G and trying to selectively disable every device driver and ACPI subsystem = possible (including USB) while still allowing me to get to a login prompt, = tweaking every sysctl I could find around ACPI, USB, debugging, etc. Nothin= g helped. Looking into Linux' ACPI support, they have acpi_no_s5, which they claim is= used for certain motherboards which lack an _S5 DSDT entry. I believe my proposed patch would be useful both for the case of a missing = _S5 entry, as well as for when there are bugs in FreeBSD, or the motherboar= d DSDT, or in Intel's ASL parser, or in the hardware itself. Obviously, it'= s most desirable to fix ACPI on the Threadripper + Taichi X399 platform, bu= t a sysctl as I'm proposing would be beneficial for this and future platfor= ms while users wait for a fix. If someone with kernel commit access would be interested, I can write all o= f the code against -CURRENT, and submit a diff patch for review. It would b= e only a small amount of code, maybe 30 lines or so, with appropriate error= checking and fallbacks in place. Again, I'm very new to this, so please be= ar with me. Personally, for now, I just monkey patched it into acpica.c and confirmed t= hat the concept works. If there's no interest, then I will drop the matter. Thank you everyone for your time!
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?LTDwcvo--3-1>