Page MenuHomeFreeBSD

EFI wake time
Needs ReviewPublic

Authored by jo_bruelltuete.com on Sep 26 2022, 2:30 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Mar 5, 5:58 PM
Unknown Object (File)
Fri, Mar 3, 10:49 AM
Unknown Object (File)
Feb 17 2023, 4:27 PM
Unknown Object (File)
Feb 17 2023, 4:27 PM
Unknown Object (File)
Feb 11 2023, 7:29 PM
Unknown Object (File)
Jan 6 2023, 8:17 AM
Unknown Object (File)
Jan 5 2023, 11:01 AM
Unknown Object (File)
Jan 5 2023, 11:01 AM
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

Expose EFI wake time API

Test Plan
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/efiio.h>

int main(int argc __unused, char **argv __unused)
{
        int efi_fd = open("/dev/efi", O_RDWR);
        if (efi_fd < 0)
        {
                printf("Error: cannot open /dev/efi\n");
                return 1;
        }

        struct efi_tm   now;
        int rv = ioctl(efi_fd, EFIIOC_GET_TIME, &now);
        printf("rv = %i, errno = %i = %s\n", rv, errno, strerror(errno));
        printf("EFI says now is: %i.%i.%i %i:%i:%i (%i)\n\n",
            now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec, now.tm_tz);

        struct efi_waketime_ioc wt;
        rv = ioctl(efi_fd, EFIIOC_GET_WAKETIME, &wt);
        printf("rv = %i, errno = %i = %s\n", rv, errno, strerror(errno));
        printf("EFI wake time is: %i.%i.%i %i:%i:%i (%i);  enabled=%i, pending=%i\n\n",
            wt.waketime.tm_year, wt.waketime.tm_mon, wt.waketime.tm_mday, wt.waketime.tm_hour,
            wt.waketime.tm_min, wt.waketime.tm_sec, wt.waketime.tm_tz, wt.enabled, wt.pending);

        wt.enabled = 1;
        wt.waketime = now;
        wt.waketime.tm_min = (wt.waketime.tm_min + 5) % 60;

        rv = ioctl(efi_fd, EFIIOC_SET_WAKETIME, &wt);
        printf("rv = %i, errno = %i = %s\n\n", rv, errno, strerror(errno));

        return 0;
}

Tested on laptop: reports unsupported.
Tested on NAS: reports everything is fine, including enabled, pending etc. BUT: does not actually wake from S3.

So no idea if this actually works...

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

I was unable to test this patch. efi.h patch fails against CURRENT. D28620 abstracted the EFI public interface functions to support Xen VMs.

The patch looks good.... for an older system. I like the concepts here, and maybe you could rebase to -current?

hi @imp & @john.grafton_runbox.com, thanks for looking!
this patch was against stable-13. I don't have spare hardware to test on current...
how useful do you think this patch is? it did not actually work for me... i suspect a dodgy bios in the nas box, as it wakes from s5 but not from s3.

Yeah, I think supporting EFI wake time could be useful to some folks. I've got a box running current I'll test with if you're able to rebase the patch.

rebase onto current.
(compiles but not runtime tested)

I tested this patch on a Lenovo T480 laptop and a generic AMD desktop running CURRENT. Both reported that they supported EFI wake time.

Unfortunately, I had the same experience you had in 13. Everything *looked* like it should work but neither system powered on or woke from S3. :(

Hm... no idea how that is supposed to work then...
I suspect that something something ACPI needs to happen.
For example, for my NAS box I have (sysctl):

dev.acpi_sysresource.3.wake: 0

which is the super-io / power management controller (cf D36424).
But messing around with that wake parameter does not seem to do anything.

I suspect the lack of actual wakeup is related to PM1.RTC_EN bit not set properly. Look up it in the section 4.8.3.1.2 PM1Enable Registers of ACPI spec v. 6.5.

thanks for the pointer, kib!
spec looks relevant. but i have no idea how to do anything about those flags in the fbsd source code...

thanks for the pointer, kib!
spec looks relevant. but i have no idea how to do anything about those flags in the fbsd source code...

I suspect it is along the lines of

AcpiWriteBitRegister(ACPI_BITREG_RT_CLOCK_ENABLE, 1);