Date: Mon, 02 Oct 2006 15:03:03 -0700 From: Nate Lawson <nate@root.org> To: John Baldwin <jhb@freebsd.org> Cc: freebsd-acpi@freebsd.org, Andrea Bittau <a.bittau@cs.ucl.ac.uk>, freebsd-mobile@freebsd.org Subject: Re: hack for getting suspend/resume to half work on an IBM Thinkpad x60s [SMP] Message-ID: <45218C97.5050802@root.org> In-Reply-To: <200610021424.18562.jhb@freebsd.org> References: <20060921000628.GA1832@shorty.sorbonet.org> <200610021424.18562.jhb@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?45218C97.5050802>