WEBVTT

00:00.000 --> 00:06.000
How's it going?

00:06.000 --> 00:09.000
So I'm going to talk about modern standby,

00:09.000 --> 00:13.000
my work I've been doing with on modern standby on 3bSC.

00:13.000 --> 00:17.000
So actually I took a 15 minute talk,

00:17.000 --> 00:19.000
because I didn't think I'd have too much to talk about,

00:19.000 --> 00:20.000
but I mean it kind of ballooned.

00:20.000 --> 00:22.000
So I might gloss over a few things,

00:22.000 --> 00:24.000
and if I speak a bit too quickly,

00:24.000 --> 00:26.000
as I tend to do, please yell,

00:26.000 --> 00:28.000
or maybe don't yell just to just make me know.

00:28.000 --> 00:31.000
Anyway, so a bit about me,

00:31.000 --> 00:35.000
my two interests, I guess, are OS's and graphics programming.

00:35.000 --> 00:38.000
I'm sponsored by the 3bSC foundation

00:38.000 --> 00:42.000
to work on a 0x and month standby,

00:42.000 --> 00:46.000
and I work at a company called Benuable, which shows

00:46.000 --> 00:49.000
as energy storage stuff in Belgium.

00:49.000 --> 00:51.000
And yeah, I spend most of my time in a train.

00:51.000 --> 00:54.000
Actually, I think my second true passion in life,

00:54.000 --> 00:56.000
apart from my dog, is trains.

00:56.000 --> 00:59.000
I'm really a huge nerd. Anyway,

00:59.000 --> 01:01.000
so a bit of background about what the issue is.

01:01.000 --> 01:04.000
So in the past, computers had something called S3,

01:04.000 --> 01:06.000
and in modern laptops,

01:06.000 --> 01:08.000
just to ease bioscivalment,

01:08.000 --> 01:12.000
this kind of got removed and favor of something called S0x.

01:12.000 --> 01:15.000
And 3bSC doesn't support S0x.

01:15.000 --> 01:18.000
Therefore, 3bSC can't sleep on long laptops,

01:18.000 --> 01:20.000
and therefore, well,

01:20.000 --> 01:23.000
3bSC can't sleep on long laptops.

01:23.000 --> 01:26.000
So a bit of previous work, Benuable dalsky from Intel,

01:26.000 --> 01:30.000
in 2018, made these two revisions.

01:30.000 --> 01:32.000
Things have kind of changed since then,

01:32.000 --> 01:35.000
so there was quite a bit of stuff to do to pick up on.

01:35.000 --> 01:37.000
And I'm going to talk about that.

01:37.000 --> 01:39.000
So, what is actually S3 exactly?

01:39.000 --> 01:42.000
So, ACPI defines a bunch of global states.

01:42.000 --> 01:45.000
You've got S0 for a system that's fully awake and running.

01:45.000 --> 01:47.000
S5 when it's off.

01:47.000 --> 01:51.000
And S3 was suspending for RAM.

01:51.000 --> 01:54.000
So RAM stays on all devices turn off,

01:54.000 --> 01:56.000
and the CPU is turned off.

01:56.000 --> 01:57.000
And then when you restart,

01:57.000 --> 02:00.000
then your RAM's already there, you don't have to do that much.

02:00.000 --> 02:03.000
And so, it's a pretty heavy-handed approach.

02:03.000 --> 02:05.000
You're just asking firmware to go to sleep,

02:05.000 --> 02:06.000
and then firmware just doesn't.

02:06.000 --> 02:08.000
And you don't really have too much control over that.

02:08.000 --> 02:10.000
And one of the implications of that is that

02:10.000 --> 02:13.000
entering an existing S3 is kind of slow.

02:13.000 --> 02:16.000
And ideally, you want it to be as quick as possible,

02:16.000 --> 02:17.000
so just be able to like,

02:17.000 --> 02:19.000
you know, close your laptop, it goes to sleep,

02:19.000 --> 02:21.000
and it'd be ready to go.

02:21.000 --> 02:24.000
So, as opposed to S3, S0iX,

02:24.000 --> 02:26.000
your system is wasting in S0.

02:26.000 --> 02:29.000
And your firmware decides when to enter S0iX,

02:29.000 --> 02:31.000
one of the S0iX states,

02:31.000 --> 02:33.000
and turn off the CPU,

02:33.000 --> 02:37.000
just depending on some power constraints.

02:37.000 --> 02:39.000
So, yeah.

02:39.000 --> 02:41.000
And so, the end goal is S0i3,

02:41.000 --> 02:43.000
that's the thing that your CPU is completely off,

02:43.000 --> 02:45.000
and that's the thing that saves the most power.

02:46.000 --> 02:48.000
So, just a bit of terminology,

02:48.000 --> 02:50.000
when I speak of a shallow or power state,

02:50.000 --> 02:52.000
that means that it's closer to being on,

02:52.000 --> 02:53.000
so that's a smaller number,

02:53.000 --> 02:54.000
so S0iX is on,

02:54.000 --> 02:55.000
that's a smaller number,

02:55.000 --> 02:57.000
it's closer to being on.

02:57.000 --> 02:59.000
Deeper is the opposite,

02:59.000 --> 03:01.000
and, yeah,

03:01.000 --> 03:04.000
LPI just stands for low power idle.

03:04.000 --> 03:07.000
So, yes.

03:07.000 --> 03:09.000
A bit of a crash course on ACPI,

03:09.000 --> 03:11.000
for a bit of context.

03:11.000 --> 03:13.000
What ACPI is,

03:13.000 --> 03:15.000
is basically your firmware exposes

03:15.000 --> 03:17.000
a bunch of information about the hardware,

03:17.000 --> 03:18.000
and something called AML,

03:18.000 --> 03:21.000
which is kind of like a bytecode.

03:21.000 --> 03:25.000
And it also contains a few methods

03:25.000 --> 03:28.000
for your OS to tell devices what to do.

03:28.000 --> 03:31.000
And so, here's an example of some decompiled AML,

03:31.000 --> 03:34.000
this is ASL, for the lid device.

03:34.000 --> 03:36.000
So, here we're defining,

03:36.000 --> 03:38.000
the firmware is defining, oh, here's this lid.

03:38.000 --> 03:41.000
This is its ID,

03:41.000 --> 03:43.000
and this is what your kernel uses to know

03:43.000 --> 03:44.000
that this is a lid device.

03:44.000 --> 03:46.000
And then here's an example of a method,

03:46.000 --> 03:48.000
which will return the state of the lid.

03:48.000 --> 03:51.000
And so, in C, how would you use that?

03:51.000 --> 03:55.000
Well, you get the integer at the lid object,

03:55.000 --> 03:57.000
and here it's saying,

03:57.000 --> 03:58.000
if there was a failure,

03:58.000 --> 04:00.000
then we default to saying that it is lid, it's open.

04:00.000 --> 04:02.000
And if there was no failure,

04:02.000 --> 04:05.000
then if the lid status is different to zero,

04:05.000 --> 04:09.000
then it means,

04:09.000 --> 04:11.000
okay, if it's not zero, then this is one,

04:11.000 --> 04:13.000
and if it is zero, then it's,

04:13.000 --> 04:15.000
it's anyway, whatever.

04:15.000 --> 04:18.000
Okay, SPMC,

04:18.000 --> 04:20.000
system power management control.

04:20.000 --> 04:24.000
So, this is the thing that defines,

04:24.000 --> 04:26.000
what I've called DSMs.

04:26.000 --> 04:30.000
So, DSMs are like these kind of multiplex functions,

04:30.000 --> 04:32.000
where it's like a specific ACPI function,

04:32.000 --> 04:35.000
where your vendor can define whatever they want on it.

04:35.000 --> 04:38.000
So, generally, the first argument is a UID

04:38.000 --> 04:40.000
that your vendor exposes,

04:40.000 --> 04:41.000
and from that, you know,

04:41.000 --> 04:42.000
that, oh, it's this UID,

04:42.000 --> 04:46.000
so I can use these specific vendor specific functions.

04:46.000 --> 04:48.000
And so, there are three,

04:48.000 --> 04:49.000
I guess, five,

04:49.000 --> 04:51.000
important ones for the SPMC.

04:51.000 --> 04:53.000
The first one is get device constraints.

04:53.000 --> 04:55.000
So, here you are asking the SPMC,

04:55.000 --> 04:58.000
oh, give me a list of the states I need to put my devices

04:58.000 --> 05:01.000
in to be able to enter a low power idle state.

05:01.000 --> 05:03.000
And then you've got display off,

05:03.000 --> 05:05.000
and entry, and exits, and display on,

05:05.000 --> 05:07.000
which are just telling firmware,

05:07.000 --> 05:09.000
oh, we're going into a sleep state,

05:09.000 --> 05:11.000
or we want to go into a sleep state,

05:11.000 --> 05:13.000
or we're exiting it.

05:13.000 --> 05:15.000
And there's a few vendor specific complications,

05:15.000 --> 05:17.000
which I kind of gloss over.

05:17.000 --> 05:19.000
Okay, next thing I want to talk about,

05:19.000 --> 05:20.000
are these states,

05:20.000 --> 05:22.000
these are those device states

05:22.000 --> 05:25.000
that you need to put your stuff in.

05:25.000 --> 05:28.000
So, D0 is on D3 is off.

05:28.000 --> 05:31.000
I'm not going to go into the difference between

05:31.000 --> 05:33.000
D3 code and D3 code,

05:33.000 --> 05:35.000
but there's some complications with that,

05:35.000 --> 05:37.000
but that's not too too important.

05:37.000 --> 05:39.000
And your which D states,

05:39.000 --> 05:43.000
you can get that by through power resources.

05:43.000 --> 05:45.000
So, here's an example of the NVMe device,

05:45.000 --> 05:49.000
where you have these power resource objects are defined,

05:49.000 --> 05:52.000
and a power resource object,

05:52.000 --> 05:55.000
it's just a list of power resources,

05:55.000 --> 05:57.000
which this specific state depends on.

05:57.000 --> 05:58.000
So, you start,

05:59.000 --> 06:01.000
if for example, you wanted to,

06:03.000 --> 06:05.000
if for example, you wanted to know it,

06:05.000 --> 06:06.000
okay,

06:06.000 --> 06:09.000
say P0 and V is on as a power state,

06:09.000 --> 06:11.000
then you know that you're in PR0,

06:11.000 --> 06:14.000
because this is the shallower state that depends on it.

06:14.000 --> 06:15.000
If this was off,

06:15.000 --> 06:18.000
then you'd be in D3 code,

06:18.000 --> 06:20.000
because you're at the lowest power state.

06:20.000 --> 06:22.000
It's roughly explained here,

06:22.000 --> 06:25.000
but again, I'm not going to go too too much into this.

06:26.000 --> 06:28.000
In the interest of time.

06:28.000 --> 06:29.000
So, suspended idle.

06:29.000 --> 06:31.000
What is suspended idle exactly?

06:31.000 --> 06:34.000
So, this is kind of distinct to,

06:34.000 --> 06:35.000
as a direct states.

06:35.000 --> 06:38.000
Suspended idle is basically just saying your CPU,

06:38.000 --> 06:40.000
stop working, just idle.

06:40.000 --> 06:42.000
And when your CPU is idle,

06:42.000 --> 06:43.000
as when you're firm,

06:43.000 --> 06:45.000
I can decide to go into a deeper sleep state.

06:45.000 --> 06:48.000
And you do this with the X86 M-Wate instruction,

06:48.000 --> 06:51.000
which is usually using conjunction with monitor,

06:51.000 --> 06:53.000
but you can give it a hint to say,

06:53.000 --> 06:56.000
instead of breaking out of the state

06:56.000 --> 06:59.000
when a specific part of a piece of RAM,

06:59.000 --> 07:01.000
or a piece of memory is modified,

07:01.000 --> 07:03.000
we break out when we get an interrupt.

07:03.000 --> 07:06.000
And then you can also define an EAX,

07:06.000 --> 07:07.000
the C-State,

07:07.000 --> 07:09.000
that we want the CPU to idle too.

07:09.000 --> 07:12.000
So, yeah,

07:12.000 --> 07:14.000
since we wake from idle on interrupts,

07:14.000 --> 07:16.000
we kind of wanted to disable all the interrupts

07:16.000 --> 07:18.000
that we have on our system,

07:18.000 --> 07:21.000
except for the ACPI interrupts,

07:22.000 --> 07:24.000
which is interrupt 9 usually.

07:24.000 --> 07:27.000
And that interrupts is basically useful wake event.

07:27.000 --> 07:29.000
So, maybe I press my power button,

07:29.000 --> 07:31.000
then I want my computer to wake,

07:31.000 --> 07:32.000
maybe I open the lid,

07:32.000 --> 07:34.000
that would be that kind of stuff.

07:34.000 --> 07:37.000
The only issue is that the firmware talks a lot,

07:37.000 --> 07:40.000
and we don't want to stop break out of idle,

07:40.000 --> 07:42.000
every single time the firmware has something to say.

07:42.000 --> 07:44.000
So, normally you do this with,

07:44.000 --> 07:47.000
you can choose up a device interrupts

07:47.000 --> 07:50.000
or sends these events with DSW.

07:50.000 --> 07:55.000
But the issue is that some pretty important weight devices

07:55.000 --> 07:59.000
are kind of hidden away behind the same GP as,

07:59.000 --> 08:03.000
or the same event number as other very talk to things.

08:03.000 --> 08:04.000
So, for example,

08:04.000 --> 08:06.000
latency on the embedded controller device,

08:06.000 --> 08:09.000
you have your lid notifications and your battery notifications.

08:09.000 --> 08:11.000
The battery in normal running,

08:11.000 --> 08:13.000
at least on my laptop sends a GP every second.

08:13.000 --> 08:16.000
So, this would interrupt the CPU every second.

08:16.000 --> 08:18.000
And you can't mask that out,

08:18.000 --> 08:20.000
because if you mask that out,

08:20.000 --> 08:22.000
then you wouldn't be able to detect

08:22.000 --> 08:24.000
when the lid opens to break out of idle,

08:24.000 --> 08:26.000
which is obviously a bit of a problem.

08:26.000 --> 08:29.000
So, the solution, I don't know,

08:29.000 --> 08:30.000
it's not super clear,

08:30.000 --> 08:32.000
signing the SPMC to enter an exit,

08:32.000 --> 08:33.000
to sleep,

08:33.000 --> 08:35.000
solves the issue.

08:35.000 --> 08:37.000
So, my battery instead of reporting its states,

08:37.000 --> 08:39.000
every second it reports every minute.

08:39.000 --> 08:42.000
But, yeah, the best effort solution,

08:42.000 --> 08:44.000
and this is what Linux does too,

08:44.000 --> 08:45.000
is to idle loop.

08:45.000 --> 08:47.000
So, if we break out of idle,

08:47.000 --> 08:49.000
we check what was the last interrupt,

08:49.000 --> 08:51.000
was the reason we broke out of idle.

08:51.000 --> 08:52.000
The last time,

08:52.000 --> 08:54.000
and if it wasn't what we considered

08:54.000 --> 08:56.000
wake device, then we go immediately back to sleep.

08:56.000 --> 08:58.000
So, not spend too much time there.

08:58.000 --> 08:59.000
Yeah.

08:59.000 --> 09:01.000
And on AMD,

09:01.000 --> 09:03.000
the SMU system measurement unit

09:03.000 --> 09:06.000
needs to be hinted that we're entering an existing sleep,

09:06.000 --> 09:08.000
and that might also tell the CPU

09:08.000 --> 09:10.000
to, or I guess, a firmware to show up,

09:10.000 --> 09:14.000
but that's not working fully yet.

09:15.000 --> 09:17.000
So, I found this kind of funny,

09:17.000 --> 09:21.000
and all these are trying to get it to stay in idle problems.

09:21.000 --> 09:25.000
Yes, they are as at a bar with Alex and Alex to Alex's.

09:25.000 --> 09:28.000
And I saw this thing, this sticker,

09:28.000 --> 09:31.000
say idle fucking sucks,

09:31.000 --> 09:32.000
for those funny.

09:32.000 --> 09:33.000
Anyway, debugging.

09:33.000 --> 09:37.000
On Intel, you have something called the low power idle state table,

09:37.000 --> 09:40.000
which basically has these residency counters,

09:40.000 --> 09:42.000
and residency counters are just,

09:42.000 --> 09:45.000
yeah, registers that count up for how long it's been in a specific state.

09:45.000 --> 09:47.000
So, you know if it's actually gone into that state.

09:47.000 --> 09:49.000
Unfortunately, oh yeah,

09:49.000 --> 09:51.000
and it's for payments as LPI and ACPI,

09:51.000 --> 09:55.000
but unfortunately, it seems like

09:55.000 --> 10:00.000
most platforms don't actually expose residency counters through that,

10:00.000 --> 10:01.000
so it's kind of useless.

10:01.000 --> 10:03.000
But on AMD, you have something called the SMU,

10:03.000 --> 10:05.000
which is a small part of the chip,

10:05.000 --> 10:08.000
and it runs this power management firmware,

10:08.000 --> 10:10.000
and you can send commands to it to ask it,

10:10.000 --> 10:13.000
oh, have I gone into SLRI-3 or not?

10:13.000 --> 10:15.000
So, that's that.

10:15.000 --> 10:17.000
So, yeah, for now, SLRI-3,

10:17.000 --> 10:19.000
we can't really answer it.

10:19.000 --> 10:21.000
There's a bit of a prerequisite for this,

10:21.000 --> 10:23.000
which is writing a USB-4 connection measure,

10:23.000 --> 10:25.000
which I'm looking into,

10:25.000 --> 10:27.000
but we'll see when that gets done.

10:27.000 --> 10:29.000
Either way, there's still quite a bit more work needed.

10:29.000 --> 10:30.000
So, demo.

10:30.000 --> 10:32.000
This might break this might not break,

10:32.000 --> 10:34.000
so I'm just going to go over these few other slides.

10:34.000 --> 10:37.000
So, future actually getting SLRI-3.

10:38.000 --> 10:40.000
I want to be able to give the users

10:40.000 --> 10:42.000
to find more complex vehicles.

10:42.000 --> 10:43.000
So, for example,

10:43.000 --> 10:46.000
always try to idle the CPU and the lid is closed.

10:46.000 --> 10:49.000
Hibernate, I'm not working on this,

10:49.000 --> 10:50.000
but this is just suspending,

10:50.000 --> 10:51.000
putting the memory to disk,

10:51.000 --> 10:53.000
so you're saving even more power,

10:53.000 --> 10:55.000
and I don't know if the termination I'm not going to go into this.

10:55.000 --> 10:58.000
So, there's a public issue tracker for all these,

10:58.000 --> 11:00.000
like, laptop-related projects, you can find this,

11:00.000 --> 11:03.000
and these tests, if it works.

11:03.000 --> 11:06.000
There's my contacts, and I'm going to try to demo.

11:06.000 --> 11:11.000
So, I should have, if I go back here and here.

11:11.000 --> 11:13.000
Let's see.

11:13.000 --> 11:16.000
I can't actually see what I'm doing on this.

11:16.000 --> 11:18.000
Let's see.

11:18.000 --> 11:19.000
It's a CTL.

11:23.000 --> 11:25.000
Okay, so here I've set the power button states

11:25.000 --> 11:27.000
to go into S2ID when I press it,

11:27.000 --> 11:28.000
and hopefully if I press this,

11:28.000 --> 11:30.000
it will go to sleep.

11:30.000 --> 11:32.000
Now, you're not going to see anything change,

11:32.000 --> 11:35.000
but trust me it's going to sleep.

11:36.000 --> 11:40.000
And now I can like press the keyboard to break out of sleep,

11:40.000 --> 11:43.000
and hopefully if no actually tested this with HDMI,

11:43.000 --> 11:46.000
it might just seem kind of work.

11:46.000 --> 11:47.000
I don't know.

11:47.000 --> 11:49.000
I went better than any expected.

11:49.000 --> 11:51.000
Anyway, that's that.

11:57.000 --> 12:00.000
Do you have time for questions?

12:00.000 --> 12:02.000
No, not too much.

12:02.000 --> 12:03.000
Not too much?

12:03.000 --> 12:04.000
Okay.

12:04.000 --> 12:07.000
I encourage you to grab this guy.

12:07.000 --> 12:09.000
I'm asking questions outside of the demo.

12:09.000 --> 12:11.000
If you have questions.

12:11.000 --> 12:12.000
Okay.

12:12.000 --> 12:13.000
Thank you very much.

12:13.000 --> 12:14.000
Yeah.

12:14.000 --> 12:15.000
Thanks for listening.

12:15.000 --> 12:16.000
Great.

