hack for getting suspend/resume to half work on an IBM Thinkpad
x60s [SMP]
Nate Lawson
nate at root.org
Mon Oct 2 15:03:15 PDT 2006
John Baldwin wrote:
> On Wednesday 20 September 2006 20:06, Andrea Bittau wrote:
>> This is a half working hack for getting suspend/resume to "work" on an IBM
>>
>> ...
>>
>> 2) apic. FreeBSD reconfigures the io apic upon resume, but not the local
> apic.
>> The patch attached to this mail fixes this. Indeed, it almost does so in
> the
>> "proper" way and not so much of a hack =D.
>
> I actually have made a full patch for APIC I think (thanks for your work as it
> reminded me about needing to resume lapic). You can find it at
> http://www.FreeBSD.org/~jhb/patches/apic_resume.patch It changes the x86
> interrupt code to resume interrupt controllers, not interrupt sources. It
> then uses this to make sure the 8259A PICs are properly reset on resume as
> well as resuming the local APIC. Can you test this w/o SMP and make sure it
> works?
Great to see this work going on. I just got a Core Duo laptop so this
would be great to see fixed.
I'm kinda disappointed you're not using newbus for your device methods,
but I think I mentioned that before.
On the reset code, shouldn't there be some delays between writes to the
registers?
+ outb(IO_ICU1, ICW1_RESET | ICW1_IC4);
+ outb(IO_ICU1 + ICU_IMR_OFFSET, IDT_IO_INTS);
[delay?]
+ outb(IO_ICU1 + ICU_IMR_OFFSET, 1 << 2);
[delay?]
+ outb(IO_ICU1 + ICU_IMR_OFFSET, ICW4_8086);
[delay?]
+ outb(IO_ICU1 + ICU_IMR_OFFSET, 0xff);
+ outb(IO_ICU1, OCW3_SEL | OCW3_RR);
+
+ outb(IO_ICU2, ICW1_RESET | ICW1_IC4);
+ outb(IO_ICU2 + ICU_IMR_OFFSET, IDT_IO_INTS + 8);
[delay?]
+ outb(IO_ICU2 + ICU_IMR_OFFSET, 2);
[delay?]
+ outb(IO_ICU2 + ICU_IMR_OFFSET, ICW4_8086);
[delay?]
+ outb(IO_ICU2 + ICU_IMR_OFFSET, 0xff);
+ outb(IO_ICU2, OCW3_SEL | OCW3_RR);
>> 3) SMP. The second core needs to be killed and woken up as appropriate.
> The
>> way I do this is quite lame.
>> - Force the second core in the idle loop by setting machdep.hlt_cpus=2.
>> - make system look like UP instead of SMP [i.e. deactivate SMP] &
> suspend.
>> - resume, wake up other core [which will run idle process] and activate
> SMP.
>
> Probably we need to get onto the BSP via sched_bind() during suspend and then
> stop the other CPUs using stop_cpus(). The hard part, however, is properly
> resuming the darn things. Do you know what mode the CPUs come back up in?
> It looks like we need to resend startup IPIs to them from your patch.
The writes to the PM registers should happen from the BSP anyway, so
sched_bind() is the right way to go. I think you need to start them up
the same as boot, including startup IPI and then enabling scheduling on
them.
--
Nate
More information about the freebsd-mobile
mailing list