Skip to content

Instantly share code, notes, and snippets.

@amshafer
Created November 16, 2018 05:11
Show Gist options
  • Save amshafer/d570a31f21c0ffcc041ad09242ff8e92 to your computer and use it in GitHub Desktop.
Save amshafer/d570a31f21c0ffcc041ad09242ff8e92 to your computer and use it in GitHub Desktop.
FreeBSD rtcwake work in progress
# Notes from implementation of RTC wake in FreeBSD
#
# Austin Shafer
The following is a preliminary idea of what a rtc enabled ACPI
driver for freebsd will look like. Some questions are attached
which will hopefully help clear up some things I saw while
learning about ACPI.
The first part of RTC support is an event handler for the
fixed event ACPI_EVENT_RTC. The handler needs to respond to a
RTC event and call the wakeup event handler. It could also
print the cause for the wakeup (RTC alarm) and other helpful
things.
This function should be something around the form of:
----------------
/*
* our RTC event handler
*/
UINT32
acpi_event_rtc (void *context)
{
/* handle anything extra before we wake up */
...
/* when we want to wake up we call this */
if (ACPI_FAILURE(AcpiOsExecute(OSL_NOTIFY_HANDLER,
acpi_invoke_wake_eventhandler, &sc->acpi_power_button_sx))) {
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
}
return_VALUE (ACPI_INTERRUPT_HANDLED);
}
/* install the event handler in acpi_enable_fixed_events */
AcpiInstallFixedEventHandler(ACPI_EVENT_RTC,
acpi_event_rtc, sc);
----------------
The second, and arguably more important, part of rtcwakeup is actually
setting the rtc to cause an alarm. Of the entire process this is the
bit I am most confused by. I will give it a stab below but keep in mind
I don't have much direct hardware experience:
I found this reference helpful. Please let me know if there is a better
one I should use:
http://stanislavs.org/helppc/cmos_ram.html
--
We can use the FADT entries for the alarm offsets into CMOS RAM. This
will look something like:
/*
* set our index to point to the day of week
* should be same as outb(0x70, 0x07)?
*
* we get the CMOS physical address from the vrtc table and our day of
* month offset from the FADT.
*/
outb(AcpiDmTableInfoVrtc0.PhysicalAddress, acpi_table_fadt->DayAlarm);
/*
* now we can set our days of the month to the 10th
*/
outb(0x71, 0xA);
--
Then the system should trigger an interrupt 8 at the time specified which
should cause us to wake up? This part is pretty unclear to me. I like having
examples as a method of teaching, but the above link was the best I could find.
If you have any ideas of what I am doing wrong or where I can go to learn more
please let me know.
My guess is that I should not be doing "outb" directly on 0x70/0x71. I will have to
read some more and see if acpica has a more clean approach to this.
I also am uncertain about how this interacts with other interrupts, especially
in a multiprocessor environment. Some of the resources online said to disable
interrupts before doing the calls to outb above.
----------------
AcpiClearEvent(ACPI_EVENT_RTC) should be used when necessary
to ensure the RTC is not flagged. "sc" is our acpi_softc structure.
Please let me know if this is horribly wrong or if I am headed
in the general direction. Hopefully I haven't made any
typos in the pseudocode above.
Questions:
- What is the VRTC and will I interact with it or will
it be handled behind the scenes?
- The dev/isa/rtc stuff (like atrtc) is unrelated because
isa is old correct?
Example files:
sys/kern/subr_rtc.c
sys/isa/rtc.h
... etc
- It appears that the code above enables the fixed events
without the use of AcpiEnableEvent. Just want to make sure
this is valid.
- Is it worth creating a flexible driver as I implement this
which would allow for a common interface for RTC chips of different
types? Sort of like the /dev/rtcN interface in linux? I have to
expose this to userspace somehow so it seems reasonable to invest the
time and create a more extensible interface.
Someone appears to have tried to add this but it doesn't seem to
use acpica and is aimed towards the atrtc driver? Again, Not sure how
related this is:
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207419
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment