- Clean up suspend/resume code for amd64.

- Call acpi_resync_clock() to reset system time before hardclock is ready
to tick.  Note we assume the current timecounter hardware and RTC are
already available for read operation.

Tested by:	mav
This commit is contained in:
Jung-uk Kim 2009-03-23 22:35:30 +00:00
parent 0755473ba2
commit d2b227cd49
4 changed files with 29 additions and 31 deletions

View File

@ -40,11 +40,12 @@ __FBSDID("$FreeBSD$");
SYSCTL_DECL(_debug_acpi);
uint32_t acpi_resume_beep;
int acpi_resume_beep;
TUNABLE_INT("debug.acpi.resume_beep", &acpi_resume_beep);
SYSCTL_UINT(_debug_acpi, OID_AUTO, resume_beep, CTLFLAG_RW, &acpi_resume_beep,
SYSCTL_INT(_debug_acpi, OID_AUTO, resume_beep, CTLFLAG_RW, &acpi_resume_beep,
0, "Beep the PC speaker when resuming");
uint32_t acpi_reset_video;
int acpi_reset_video;
TUNABLE_INT("hw.acpi.reset_video", &acpi_reset_video);
static int intr_model = ACPI_INTR_PIC;

View File

@ -2,7 +2,7 @@
* Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org>
* Copyright (c) 2001 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
* Copyright (c) 2003 Peter Wemm
* Copyright (c) 2008 Jung-uk Kim <jkim@FreeBSD.org>
* Copyright (c) 2008-2009 Jung-uk Kim <jkim@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -66,12 +66,14 @@ wakeup_start:
mov %ax, %ds /* are offsets rather than selectors */
mov %ax, %ss
movw $PAGE_SIZE - 8, %sp
pushw $0
xorw %ax, %ax
pushw %ax
popfw
/* To debug resume hangs, beep the speaker if the user requested. */
cmpw $0, resume_beep - wakeup_start
je 1f
testb $~0, resume_beep - wakeup_start
jz 1f
movb $0, resume_beep - wakeup_start
movb $0xc0, %al
outb %al, $0x42
movb $0x04, %al
@ -79,22 +81,16 @@ wakeup_start:
inb $0x61, %al
orb $0x3, %al
outb %al, $0x61
movw $0, resume_beep - wakeup_start
1:
/* Re-initialize video BIOS if the reset_video tunable is set. */
cmpw $0, reset_video - wakeup_start
je 1f
testb $~0, reset_video - wakeup_start
jz 1f
movb $0, reset_video - wakeup_start
lcall $0xc000, $3
movw $0, reset_video - wakeup_start
/*
* Set up segment registers for real mode again in case the
* previous BIOS call clobbers them.
*/
mov %cs, %ax
mov %ax, %ds
mov %ax, %ss
/* Re-start in case the previous BIOS call clobbers them. */
jmp wakeup_start
1:
/*
@ -204,6 +200,7 @@ wakeup_sw64:
* space. Remember that jmp is relative and that we've been relocated,
* so use an indirect jump.
*/
ALIGN_TEXT
.code64
wakeup_64:
mov $bootdata64 - bootgdt, %eax
@ -215,6 +212,13 @@ wakeup_64:
movq wakeup_retaddr - wakeup_start(%rbx), %rax
jmp *%rax
.data
resume_beep:
.byte 0
reset_video:
.byte 0
ALIGN_DATA
bootgdt:
.long 0x00000000
@ -245,10 +249,6 @@ bootgdtdesc:
.long bootgdt - wakeup_start /* Offset plus %ds << 4 */
ALIGN_DATA
resume_beep:
.long 0
reset_video:
.long 0
wakeup_retaddr:
.quad 0
wakeup_kpml4:

View File

@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/memrange.h>
#include <sys/smp.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <vm/vm.h>
@ -67,8 +66,8 @@ CTASSERT(sizeof(wakecode) < PAGE_SIZE - 1024);
#error this file needs sys/cdefs.h as a prerequisite
#endif
extern uint32_t acpi_resume_beep;
extern uint32_t acpi_reset_video;
extern int acpi_resume_beep;
extern int acpi_reset_video;
#ifdef SMP
extern struct xpcb *stopxpcbs;
@ -280,8 +279,8 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
}
#endif
WAKECODE_FIXUP(resume_beep, uint32_t, acpi_resume_beep);
WAKECODE_FIXUP(reset_video, uint32_t, acpi_reset_video);
WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0));
WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0));
WAKECODE_FIXUP(wakeup_xpcb, struct xpcb *, &stopxpcbs[0]);
WAKECODE_FIXUP(wakeup_gdt, uint16_t,
@ -309,13 +308,11 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
ia32_pause();
} else {
fpusetregs(curthread, stopfpu);
WAKECODE_FIXUP(resume_beep, uint32_t, 0);
WAKECODE_FIXUP(reset_video, uint32_t, 0);
#ifdef SMP
if (wakeup_cpus != 0)
acpi_wakeup_cpus(sc, wakeup_cpus);
#endif
acpi_resync_clock(sc);
ret = 0;
}

View File

@ -1,6 +1,6 @@
#!/bin/sh
# $FreeBSD$
#
file2c 'static char wakecode[] = {' '};' <acpi_wakecode.bin
file2c -sx 'static char wakecode[] = {' '};' <acpi_wakecode.bin
exit 0