Date: Thu, 8 Oct 2009 17:41:53 +0000 (UTC) From: Jung-uk Kim <jkim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r197863 - head/sys/amd64/acpica Message-ID: <200910081741.n98HfrI3028811@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jkim Date: Thu Oct 8 17:41:53 2009 New Revision: 197863 URL: http://svn.freebsd.org/changeset/base/197863 Log: Clean up amd64 suspend/resume code. - Allocate memory for wakeup code after ACPI bus is attached. The early memory allocation hack was inherited from i386 but amd64 does not need it. - Exclude real mode IVT and BDA explicitly. Improve comments about memory allocation and reason for the exclusions. It is a no-op in reality, though. - Remove an unnecessary CLD from wakeup code and re-align. Modified: head/sys/amd64/acpica/acpi_machdep.c head/sys/amd64/acpica/acpi_wakecode.S head/sys/amd64/acpica/acpi_wakeup.c Modified: head/sys/amd64/acpica/acpi_machdep.c ============================================================================== --- head/sys/amd64/acpica/acpi_machdep.c Thu Oct 8 17:11:01 2009 (r197862) +++ head/sys/amd64/acpica/acpi_machdep.c Thu Oct 8 17:41:53 2009 (r197863) @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/module.h> #include <sys/sysctl.h> + #include <vm/vm.h> #include <vm/pmap.h> @@ -511,7 +512,6 @@ acpi_machdep_init(device_t dev) sc->acpi_clone = apm_create_clone(sc->acpi_dev_t, sc); clone_setup(&apm_clones); EVENTHANDLER_REGISTER(dev_clone, apm_clone, 0, 1000); - acpi_install_wakeup_handler(sc); if (intr_model != ACPI_INTR_PIC) acpi_SetIntrModel(intr_model); @@ -801,13 +801,20 @@ nexus_acpi_probe(device_t dev) static int nexus_acpi_attach(device_t dev) { + device_t acpi_dev; + int error; nexus_init_resources(); bus_generic_probe(dev); - if (BUS_ADD_CHILD(dev, 10, "acpi", 0) == NULL) + acpi_dev = BUS_ADD_CHILD(dev, 10, "acpi", 0); + if (acpi_dev == NULL) panic("failed to add acpi0 device"); - return (bus_generic_attach(dev)); + error = bus_generic_attach(dev); + if (error == 0) + acpi_install_wakeup_handler(device_get_softc(acpi_dev)); + + return (error); } static device_method_t nexus_acpi_methods[] = { Modified: head/sys/amd64/acpica/acpi_wakecode.S ============================================================================== --- head/sys/amd64/acpica/acpi_wakecode.S Thu Oct 8 17:11:01 2009 (r197862) +++ head/sys/amd64/acpica/acpi_wakecode.S Thu Oct 8 17:41:53 2009 (r197863) @@ -54,18 +54,17 @@ .data /* So we can modify it */ ALIGN_TEXT -wakeup_start: .code16 +wakeup_start: /* * Set up segment registers for real mode, a small stack for * any calls we make, and clear any flags. */ cli /* make sure no interrupts */ - cld mov %cs, %ax /* copy %cs to %ds. Remember these */ mov %ax, %ds /* are offsets rather than selectors */ mov %ax, %ss - movw $PAGE_SIZE - 8, %sp + movw $PAGE_SIZE, %sp xorw %ax, %ax pushw %ax popfw @@ -129,6 +128,7 @@ wakeup_sw32: /* * At this point, we are running in 32 bit legacy protected mode. */ + ALIGN_TEXT .code32 wakeup_32: Modified: head/sys/amd64/acpica/acpi_wakeup.c ============================================================================== --- head/sys/amd64/acpica/acpi_wakeup.c Thu Oct 8 17:11:01 2009 (r197862) +++ head/sys/amd64/acpica/acpi_wakeup.c Thu Oct 8 17:41:53 2009 (r197863) @@ -31,13 +31,11 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> -#include <sys/systm.h> #include <sys/bus.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/memrange.h> #include <sys/smp.h> -#include <sys/types.h> #include <vm/vm.h> #include <vm/pmap.h> @@ -46,11 +44,11 @@ __FBSDID("$FreeBSD$"); #include <machine/pcb.h> #include <machine/pmap.h> #include <machine/specialreg.h> -#include <machine/vmparam.h> #ifdef SMP #include <machine/apicreg.h> #include <machine/smp.h> +#include <machine/vmparam.h> #endif #include <contrib/dev/acpica/include/acpi.h> @@ -63,10 +61,6 @@ __FBSDID("$FreeBSD$"); /* Make sure the code is less than a page and leave room for the stack. */ CTASSERT(sizeof(wakecode) < PAGE_SIZE - 1024); -#ifndef _SYS_CDEFS_H_ -#error this file needs sys/cdefs.h as a prerequisite -#endif - extern int acpi_resume_beep; extern int acpi_reset_video; @@ -79,7 +73,7 @@ static struct xpcb *stopxpcbs; int acpi_restorecpu(struct xpcb *, vm_offset_t); int acpi_savecpu(struct xpcb *); -static void acpi_alloc_wakeup_handler(void); +static void *acpi_alloc_wakeup_handler(void); static void acpi_stop_beep(void *); #ifdef SMP @@ -322,49 +316,50 @@ out: return (ret); } -static vm_offset_t acpi_wakeaddr; - -static void +static void * acpi_alloc_wakeup_handler(void) { void *wakeaddr; - if (!cold) - return; - /* * Specify the region for our wakeup code. We want it in the low 1 MB - * region, excluding video memory and above (0xa0000). We ask for - * it to be page-aligned, just to be safe. + * region, excluding real mode IVT (0-0x3ff), BDA (0x400-0x4ff), EBDA + * (less than 128KB, below 0xa0000, must be excluded by SMAP and DSDT), + * and ROM area (0xa0000 and above). The temporary page tables must be + * page-aligned. */ - wakeaddr = contigmalloc(4 * PAGE_SIZE, M_DEVBUF, M_NOWAIT, 0, 0x9ffff, - PAGE_SIZE, 0ul); + wakeaddr = contigmalloc(4 * PAGE_SIZE, M_DEVBUF, M_NOWAIT, 0x500, + 0xa0000, PAGE_SIZE, 0ul); if (wakeaddr == NULL) { printf("%s: can't alloc wake memory\n", __func__); - return; + return (NULL); } stopxpcbs = malloc(mp_ncpus * sizeof(*stopxpcbs), M_DEVBUF, M_NOWAIT); if (stopxpcbs == NULL) { contigfree(wakeaddr, 4 * PAGE_SIZE, M_DEVBUF); printf("%s: can't alloc CPU state memory\n", __func__); - return; + return (NULL); } - acpi_wakeaddr = (vm_offset_t)wakeaddr; -} -SYSINIT(acpiwakeup, SI_SUB_KMEM, SI_ORDER_ANY, acpi_alloc_wakeup_handler, 0); + return (wakeaddr); +} void acpi_install_wakeup_handler(struct acpi_softc *sc) { + static void *wakeaddr = NULL; uint64_t *pt4, *pt3, *pt2; int i; - if (acpi_wakeaddr == 0ul) + if (wakeaddr != NULL) + return; + + wakeaddr = acpi_alloc_wakeup_handler(); + if (wakeaddr == NULL) return; - sc->acpi_wakeaddr = acpi_wakeaddr; - sc->acpi_wakephys = vtophys(acpi_wakeaddr); + sc->acpi_wakeaddr = (vm_offset_t)wakeaddr; + sc->acpi_wakephys = vtophys(wakeaddr); bcopy(wakecode, (void *)WAKECODE_VADDR(sc), sizeof(wakecode)); @@ -390,7 +385,7 @@ acpi_install_wakeup_handler(struct acpi_ WAKECODE_FIXUP(wakeup_sfmask, uint64_t, rdmsr(MSR_SF_MASK)); /* Build temporary page tables below realmode code. */ - pt4 = (uint64_t *)acpi_wakeaddr; + pt4 = wakeaddr; pt3 = pt4 + (PAGE_SIZE) / sizeof(uint64_t); pt2 = pt3 + (PAGE_SIZE) / sizeof(uint64_t);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910081741.n98HfrI3028811>