2001-07-20 06:07:34 +00:00
|
|
|
/*-
|
|
|
|
* Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org>
|
|
|
|
* Copyright (c) 2001 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
|
2009-03-17 00:48:11 +00:00
|
|
|
* Copyright (c) 2003 Peter Wemm
|
2012-01-31 17:51:30 +00:00
|
|
|
* Copyright (c) 2008-2012 Jung-uk Kim <jkim@FreeBSD.org>
|
2001-07-20 06:07:34 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
2003-07-25 21:10:19 +00:00
|
|
|
|
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
2001-07-20 06:07:34 +00:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/bus.h>
|
2012-02-15 22:49:25 +00:00
|
|
|
#include <sys/eventhandler.h>
|
2009-03-17 00:48:11 +00:00
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/memrange.h>
|
|
|
|
#include <sys/smp.h>
|
|
|
|
|
|
|
|
#include <vm/vm.h>
|
|
|
|
#include <vm/pmap.h>
|
|
|
|
|
2012-02-15 22:49:25 +00:00
|
|
|
#include <machine/clock.h>
|
2009-03-17 00:48:11 +00:00
|
|
|
#include <machine/intr_machdep.h>
|
2010-11-01 17:40:35 +00:00
|
|
|
#include <x86/mca.h>
|
2009-03-17 00:48:11 +00:00
|
|
|
#include <machine/pcb.h>
|
|
|
|
#include <machine/pmap.h>
|
|
|
|
#include <machine/specialreg.h>
|
Add support for the extended FPU states on amd64, both for native
64bit and 32bit ABIs. As a side-effect, it enables AVX on capable
CPUs.
In particular:
- Query the CPU support for XSAVE, list of the supported extensions
and the required size of FPU save area. The hw.use_xsave tunable is
provided for disabling XSAVE, and hw.xsave_mask may be used to
select the enabled extensions.
- Remove the FPU save area from PCB and dynamically allocate the
(run-time sized) user save area on the top of the kernel stack,
right above the PCB. Reorganize the thread0 PCB initialization to
postpone it after BSP is queried for save area size.
- The dumppcb, stoppcbs and susppcbs now do not carry the FPU state as
well. FPU state is only useful for suspend, where it is saved in
dynamically allocated suspfpusave area.
- Use XSAVE and XRSTOR to save/restore FPU state, if supported and
enabled.
- Define new mcontext_t flag _MC_HASFPXSTATE, indicating that
mcontext_t has a valid pointer to out-of-struct extended FPU
state. Signal handlers are supplied with stack-allocated fpu
state. The sigreturn(2) and setcontext(2) syscall honour the flag,
allowing the signal handlers to inspect and manipilate extended
state in the interrupted context.
- The getcontext(2) never returns extended state, since there is no
place in the fixed-sized mcontext_t to place variable-sized save
area. And, since mcontext_t is embedded into ucontext_t, makes it
impossible to fix in a reasonable way. Instead of extending
getcontext(2) syscall, provide a sysarch(2) facility to query
extended FPU state.
- Add ptrace(2) support for getting and setting extended state; while
there, implement missed PT_I386_{GET,SET}XMMREGS for 32bit binaries.
- Change fpu_kern KPI to not expose struct fpu_kern_ctx layout to
consumers, making it opaque. Internally, struct fpu_kern_ctx now
contains a space for the extended state. Convert in-kernel consumers
of fpu_kern KPI both on i386 and amd64.
First version of the support for AVX was submitted by Tim Bird
<tim.bird am sony com> on behalf of Sony. This version was written
from scratch.
Tested by: pho (previous version), Yamagi Burmeister <lists yamagi org>
MFC after: 1 month
2012-01-21 17:45:27 +00:00
|
|
|
#include <machine/md_var.h>
|
2009-03-17 00:48:11 +00:00
|
|
|
|
|
|
|
#ifdef SMP
|
2010-11-01 18:18:46 +00:00
|
|
|
#include <x86/apicreg.h>
|
2009-03-17 00:48:11 +00:00
|
|
|
#include <machine/smp.h>
|
2009-10-08 17:41:53 +00:00
|
|
|
#include <machine/vmparam.h>
|
2009-03-17 00:48:11 +00:00
|
|
|
#endif
|
2001-07-20 06:07:34 +00:00
|
|
|
|
2009-06-05 18:44:36 +00:00
|
|
|
#include <contrib/dev/acpica/include/acpi.h>
|
|
|
|
|
2001-07-20 06:07:34 +00:00
|
|
|
#include <dev/acpica/acpivar.h>
|
|
|
|
|
2009-03-17 00:48:11 +00:00
|
|
|
#include "acpi_wakecode.h"
|
|
|
|
#include "acpi_wakedata.h"
|
|
|
|
|
|
|
|
/* Make sure the code is less than a page and leave room for the stack. */
|
|
|
|
CTASSERT(sizeof(wakecode) < PAGE_SIZE - 1024);
|
|
|
|
|
2009-03-23 22:35:30 +00:00
|
|
|
extern int acpi_resume_beep;
|
|
|
|
extern int acpi_reset_video;
|
2009-03-17 00:48:11 +00:00
|
|
|
|
|
|
|
#ifdef SMP
|
2010-08-02 17:35:00 +00:00
|
|
|
extern struct pcb **susppcbs;
|
Add support for the extended FPU states on amd64, both for native
64bit and 32bit ABIs. As a side-effect, it enables AVX on capable
CPUs.
In particular:
- Query the CPU support for XSAVE, list of the supported extensions
and the required size of FPU save area. The hw.use_xsave tunable is
provided for disabling XSAVE, and hw.xsave_mask may be used to
select the enabled extensions.
- Remove the FPU save area from PCB and dynamically allocate the
(run-time sized) user save area on the top of the kernel stack,
right above the PCB. Reorganize the thread0 PCB initialization to
postpone it after BSP is queried for save area size.
- The dumppcb, stoppcbs and susppcbs now do not carry the FPU state as
well. FPU state is only useful for suspend, where it is saved in
dynamically allocated suspfpusave area.
- Use XSAVE and XRSTOR to save/restore FPU state, if supported and
enabled.
- Define new mcontext_t flag _MC_HASFPXSTATE, indicating that
mcontext_t has a valid pointer to out-of-struct extended FPU
state. Signal handlers are supplied with stack-allocated fpu
state. The sigreturn(2) and setcontext(2) syscall honour the flag,
allowing the signal handlers to inspect and manipilate extended
state in the interrupted context.
- The getcontext(2) never returns extended state, since there is no
place in the fixed-sized mcontext_t to place variable-sized save
area. And, since mcontext_t is embedded into ucontext_t, makes it
impossible to fix in a reasonable way. Instead of extending
getcontext(2) syscall, provide a sysarch(2) facility to query
extended FPU state.
- Add ptrace(2) support for getting and setting extended state; while
there, implement missed PT_I386_{GET,SET}XMMREGS for 32bit binaries.
- Change fpu_kern KPI to not expose struct fpu_kern_ctx layout to
consumers, making it opaque. Internally, struct fpu_kern_ctx now
contains a space for the extended state. Convert in-kernel consumers
of fpu_kern KPI both on i386 and amd64.
First version of the support for AVX was submitted by Tim Bird
<tim.bird am sony com> on behalf of Sony. This version was written
from scratch.
Tested by: pho (previous version), Yamagi Burmeister <lists yamagi org>
MFC after: 1 month
2012-01-21 17:45:27 +00:00
|
|
|
extern void **suspfpusave;
|
2009-03-17 00:48:11 +00:00
|
|
|
#else
|
2010-08-02 17:35:00 +00:00
|
|
|
static struct pcb **susppcbs;
|
Add support for the extended FPU states on amd64, both for native
64bit and 32bit ABIs. As a side-effect, it enables AVX on capable
CPUs.
In particular:
- Query the CPU support for XSAVE, list of the supported extensions
and the required size of FPU save area. The hw.use_xsave tunable is
provided for disabling XSAVE, and hw.xsave_mask may be used to
select the enabled extensions.
- Remove the FPU save area from PCB and dynamically allocate the
(run-time sized) user save area on the top of the kernel stack,
right above the PCB. Reorganize the thread0 PCB initialization to
postpone it after BSP is queried for save area size.
- The dumppcb, stoppcbs and susppcbs now do not carry the FPU state as
well. FPU state is only useful for suspend, where it is saved in
dynamically allocated suspfpusave area.
- Use XSAVE and XRSTOR to save/restore FPU state, if supported and
enabled.
- Define new mcontext_t flag _MC_HASFPXSTATE, indicating that
mcontext_t has a valid pointer to out-of-struct extended FPU
state. Signal handlers are supplied with stack-allocated fpu
state. The sigreturn(2) and setcontext(2) syscall honour the flag,
allowing the signal handlers to inspect and manipilate extended
state in the interrupted context.
- The getcontext(2) never returns extended state, since there is no
place in the fixed-sized mcontext_t to place variable-sized save
area. And, since mcontext_t is embedded into ucontext_t, makes it
impossible to fix in a reasonable way. Instead of extending
getcontext(2) syscall, provide a sysarch(2) facility to query
extended FPU state.
- Add ptrace(2) support for getting and setting extended state; while
there, implement missed PT_I386_{GET,SET}XMMREGS for 32bit binaries.
- Change fpu_kern KPI to not expose struct fpu_kern_ctx layout to
consumers, making it opaque. Internally, struct fpu_kern_ctx now
contains a space for the extended state. Convert in-kernel consumers
of fpu_kern KPI both on i386 and amd64.
First version of the support for AVX was submitted by Tim Bird
<tim.bird am sony com> on behalf of Sony. This version was written
from scratch.
Tested by: pho (previous version), Yamagi Burmeister <lists yamagi org>
MFC after: 1 month
2012-01-21 17:45:27 +00:00
|
|
|
static void **suspfpusave;
|
2009-03-17 00:48:11 +00:00
|
|
|
#endif
|
|
|
|
|
2012-02-03 21:21:00 +00:00
|
|
|
int acpi_restorecpu(uint64_t, vm_offset_t);
|
2009-03-17 00:48:11 +00:00
|
|
|
|
2009-10-08 17:41:53 +00:00
|
|
|
static void *acpi_alloc_wakeup_handler(void);
|
2009-03-17 00:48:11 +00:00
|
|
|
static void acpi_stop_beep(void *);
|
|
|
|
|
|
|
|
#ifdef SMP
|
|
|
|
static int acpi_wakeup_ap(struct acpi_softc *, int);
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
static void acpi_wakeup_cpus(struct acpi_softc *, const cpuset_t *);
|
2009-03-17 00:48:11 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define WAKECODE_VADDR(sc) ((sc)->acpi_wakeaddr + (3 * PAGE_SIZE))
|
|
|
|
#define WAKECODE_PADDR(sc) ((sc)->acpi_wakephys + (3 * PAGE_SIZE))
|
|
|
|
#define WAKECODE_FIXUP(offset, type, val) do { \
|
|
|
|
type *addr; \
|
|
|
|
addr = (type *)(WAKECODE_VADDR(sc) + offset); \
|
|
|
|
*addr = val; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
static void
|
|
|
|
acpi_stop_beep(void *arg)
|
|
|
|
{
|
2012-02-15 22:49:25 +00:00
|
|
|
|
2012-02-16 22:28:17 +00:00
|
|
|
if (acpi_resume_beep != 0)
|
|
|
|
timer_spkr_release();
|
2009-03-17 00:48:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SMP
|
|
|
|
static int
|
|
|
|
acpi_wakeup_ap(struct acpi_softc *sc, int cpu)
|
|
|
|
{
|
|
|
|
int vector = (WAKECODE_PADDR(sc) >> 12) & 0xff;
|
|
|
|
int apic_id = cpu_apic_ids[cpu];
|
|
|
|
int ms;
|
|
|
|
|
2010-08-02 17:35:00 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_pcb, struct pcb *, susppcbs[cpu]);
|
Add support for the extended FPU states on amd64, both for native
64bit and 32bit ABIs. As a side-effect, it enables AVX on capable
CPUs.
In particular:
- Query the CPU support for XSAVE, list of the supported extensions
and the required size of FPU save area. The hw.use_xsave tunable is
provided for disabling XSAVE, and hw.xsave_mask may be used to
select the enabled extensions.
- Remove the FPU save area from PCB and dynamically allocate the
(run-time sized) user save area on the top of the kernel stack,
right above the PCB. Reorganize the thread0 PCB initialization to
postpone it after BSP is queried for save area size.
- The dumppcb, stoppcbs and susppcbs now do not carry the FPU state as
well. FPU state is only useful for suspend, where it is saved in
dynamically allocated suspfpusave area.
- Use XSAVE and XRSTOR to save/restore FPU state, if supported and
enabled.
- Define new mcontext_t flag _MC_HASFPXSTATE, indicating that
mcontext_t has a valid pointer to out-of-struct extended FPU
state. Signal handlers are supplied with stack-allocated fpu
state. The sigreturn(2) and setcontext(2) syscall honour the flag,
allowing the signal handlers to inspect and manipilate extended
state in the interrupted context.
- The getcontext(2) never returns extended state, since there is no
place in the fixed-sized mcontext_t to place variable-sized save
area. And, since mcontext_t is embedded into ucontext_t, makes it
impossible to fix in a reasonable way. Instead of extending
getcontext(2) syscall, provide a sysarch(2) facility to query
extended FPU state.
- Add ptrace(2) support for getting and setting extended state; while
there, implement missed PT_I386_{GET,SET}XMMREGS for 32bit binaries.
- Change fpu_kern KPI to not expose struct fpu_kern_ctx layout to
consumers, making it opaque. Internally, struct fpu_kern_ctx now
contains a space for the extended state. Convert in-kernel consumers
of fpu_kern KPI both on i386 and amd64.
First version of the support for AVX was submitted by Tim Bird
<tim.bird am sony com> on behalf of Sony. This version was written
from scratch.
Tested by: pho (previous version), Yamagi Burmeister <lists yamagi org>
MFC after: 1 month
2012-01-21 17:45:27 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_fpusave, void *, suspfpusave[cpu]);
|
2010-08-02 17:35:00 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_gdt, uint16_t, susppcbs[cpu]->pcb_gdt.rd_limit);
|
2009-03-17 00:48:11 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t,
|
2010-08-02 17:35:00 +00:00
|
|
|
susppcbs[cpu]->pcb_gdt.rd_base);
|
2009-03-17 00:48:11 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_cpu, int, cpu);
|
|
|
|
|
|
|
|
/* do an INIT IPI: assert RESET */
|
|
|
|
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
|
|
|
|
APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id);
|
|
|
|
|
|
|
|
/* wait for pending status end */
|
|
|
|
lapic_ipi_wait(-1);
|
|
|
|
|
|
|
|
/* do an INIT IPI: deassert RESET */
|
|
|
|
lapic_ipi_raw(APIC_DEST_ALLESELF | APIC_TRIGMOD_LEVEL |
|
|
|
|
APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, 0);
|
|
|
|
|
|
|
|
/* wait for pending status end */
|
|
|
|
DELAY(10000); /* wait ~10mS */
|
|
|
|
lapic_ipi_wait(-1);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* next we do a STARTUP IPI: the previous INIT IPI might still be
|
|
|
|
* latched, (P5 bug) this 1st STARTUP would then terminate
|
|
|
|
* immediately, and the previously started INIT IPI would continue. OR
|
|
|
|
* the previous INIT IPI has already run. and this STARTUP IPI will
|
|
|
|
* run. OR the previous INIT IPI was ignored. and this STARTUP IPI
|
|
|
|
* will run.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* do a STARTUP IPI */
|
|
|
|
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
|
|
|
|
APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
|
|
|
|
vector, apic_id);
|
|
|
|
lapic_ipi_wait(-1);
|
|
|
|
DELAY(200); /* wait ~200uS */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF
|
|
|
|
* the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
|
|
|
|
* this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
|
|
|
|
* recognized after hardware RESET or INIT IPI.
|
|
|
|
*/
|
|
|
|
|
|
|
|
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
|
|
|
|
APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
|
|
|
|
vector, apic_id);
|
|
|
|
lapic_ipi_wait(-1);
|
|
|
|
DELAY(200); /* wait ~200uS */
|
|
|
|
|
|
|
|
/* Wait up to 5 seconds for it to start. */
|
|
|
|
for (ms = 0; ms < 5000; ms++) {
|
|
|
|
if (*(int *)(WAKECODE_VADDR(sc) + wakeup_cpu) == 0)
|
|
|
|
return (1); /* return SUCCESS */
|
|
|
|
DELAY(1000);
|
|
|
|
}
|
|
|
|
return (0); /* return FAILURE */
|
|
|
|
}
|
|
|
|
|
|
|
|
#define WARMBOOT_TARGET 0
|
|
|
|
#define WARMBOOT_OFF (KERNBASE + 0x0467)
|
|
|
|
#define WARMBOOT_SEG (KERNBASE + 0x0469)
|
|
|
|
|
|
|
|
#define CMOS_REG (0x70)
|
|
|
|
#define CMOS_DATA (0x71)
|
|
|
|
#define BIOS_RESET (0x0f)
|
|
|
|
#define BIOS_WARM (0x0a)
|
|
|
|
|
|
|
|
static void
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
acpi_wakeup_cpus(struct acpi_softc *sc, const cpuset_t *wakeup_cpus)
|
2009-03-17 00:48:11 +00:00
|
|
|
{
|
|
|
|
uint32_t mpbioswarmvec;
|
|
|
|
int cpu;
|
|
|
|
u_char mpbiosreason;
|
|
|
|
|
|
|
|
/* save the current value of the warm-start vector */
|
|
|
|
mpbioswarmvec = *((uint32_t *)WARMBOOT_OFF);
|
|
|
|
outb(CMOS_REG, BIOS_RESET);
|
|
|
|
mpbiosreason = inb(CMOS_DATA);
|
|
|
|
|
|
|
|
/* setup a vector to our boot code */
|
|
|
|
*((volatile u_short *)WARMBOOT_OFF) = WARMBOOT_TARGET;
|
|
|
|
*((volatile u_short *)WARMBOOT_SEG) = WAKECODE_PADDR(sc) >> 4;
|
|
|
|
outb(CMOS_REG, BIOS_RESET);
|
|
|
|
outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */
|
|
|
|
|
|
|
|
/* Wake up each AP. */
|
|
|
|
for (cpu = 1; cpu < mp_ncpus; cpu++) {
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
if (!CPU_ISSET(cpu, wakeup_cpus))
|
2009-03-17 00:48:11 +00:00
|
|
|
continue;
|
|
|
|
if (acpi_wakeup_ap(sc, cpu) == 0) {
|
|
|
|
/* restore the warmstart vector */
|
|
|
|
*(uint32_t *)WARMBOOT_OFF = mpbioswarmvec;
|
|
|
|
panic("acpi_wakeup: failed to resume AP #%d (PHY #%d)",
|
|
|
|
cpu, cpu_apic_ids[cpu]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* restore the warmstart vector */
|
|
|
|
*(uint32_t *)WARMBOOT_OFF = mpbioswarmvec;
|
|
|
|
|
|
|
|
outb(CMOS_REG, BIOS_RESET);
|
|
|
|
outb(CMOS_DATA, mpbiosreason);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-07-20 06:07:34 +00:00
|
|
|
int
|
|
|
|
acpi_sleep_machdep(struct acpi_softc *sc, int state)
|
|
|
|
{
|
2009-03-17 00:48:11 +00:00
|
|
|
#ifdef SMP
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
cpuset_t wakeup_cpus;
|
2009-03-17 00:48:11 +00:00
|
|
|
#endif
|
2012-03-20 20:37:23 +00:00
|
|
|
register_t rf;
|
2009-03-17 00:48:11 +00:00
|
|
|
ACPI_STATUS status;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = -1;
|
|
|
|
|
|
|
|
if (sc->acpi_wakeaddr == 0ul)
|
|
|
|
return (ret);
|
|
|
|
|
|
|
|
#ifdef SMP
|
2011-06-21 09:19:38 +00:00
|
|
|
wakeup_cpus = all_cpus;
|
|
|
|
CPU_CLR(PCPU_GET(cpuid), &wakeup_cpus);
|
2009-03-17 00:48:11 +00:00
|
|
|
#endif
|
|
|
|
|
2012-02-16 22:28:17 +00:00
|
|
|
if (acpi_resume_beep != 0)
|
|
|
|
timer_spkr_acquire();
|
2012-02-15 22:49:25 +00:00
|
|
|
|
2009-03-17 00:48:11 +00:00
|
|
|
AcpiSetFirmwareWakingVector(WAKECODE_PADDR(sc));
|
|
|
|
|
2012-03-20 20:37:23 +00:00
|
|
|
rf = intr_disable();
|
2009-03-17 00:48:11 +00:00
|
|
|
intr_suspend();
|
|
|
|
|
2010-08-02 17:35:00 +00:00
|
|
|
if (savectx(susppcbs[0])) {
|
Add support for the extended FPU states on amd64, both for native
64bit and 32bit ABIs. As a side-effect, it enables AVX on capable
CPUs.
In particular:
- Query the CPU support for XSAVE, list of the supported extensions
and the required size of FPU save area. The hw.use_xsave tunable is
provided for disabling XSAVE, and hw.xsave_mask may be used to
select the enabled extensions.
- Remove the FPU save area from PCB and dynamically allocate the
(run-time sized) user save area on the top of the kernel stack,
right above the PCB. Reorganize the thread0 PCB initialization to
postpone it after BSP is queried for save area size.
- The dumppcb, stoppcbs and susppcbs now do not carry the FPU state as
well. FPU state is only useful for suspend, where it is saved in
dynamically allocated suspfpusave area.
- Use XSAVE and XRSTOR to save/restore FPU state, if supported and
enabled.
- Define new mcontext_t flag _MC_HASFPXSTATE, indicating that
mcontext_t has a valid pointer to out-of-struct extended FPU
state. Signal handlers are supplied with stack-allocated fpu
state. The sigreturn(2) and setcontext(2) syscall honour the flag,
allowing the signal handlers to inspect and manipilate extended
state in the interrupted context.
- The getcontext(2) never returns extended state, since there is no
place in the fixed-sized mcontext_t to place variable-sized save
area. And, since mcontext_t is embedded into ucontext_t, makes it
impossible to fix in a reasonable way. Instead of extending
getcontext(2) syscall, provide a sysarch(2) facility to query
extended FPU state.
- Add ptrace(2) support for getting and setting extended state; while
there, implement missed PT_I386_{GET,SET}XMMREGS for 32bit binaries.
- Change fpu_kern KPI to not expose struct fpu_kern_ctx layout to
consumers, making it opaque. Internally, struct fpu_kern_ctx now
contains a space for the extended state. Convert in-kernel consumers
of fpu_kern KPI both on i386 and amd64.
First version of the support for AVX was submitted by Tim Bird
<tim.bird am sony com> on behalf of Sony. This version was written
from scratch.
Tested by: pho (previous version), Yamagi Burmeister <lists yamagi org>
MFC after: 1 month
2012-01-21 17:45:27 +00:00
|
|
|
ctx_fpusave(suspfpusave[0]);
|
2009-03-17 00:48:11 +00:00
|
|
|
#ifdef SMP
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
if (!CPU_EMPTY(&wakeup_cpus) &&
|
|
|
|
suspend_cpus(wakeup_cpus) == 0) {
|
|
|
|
device_printf(sc->acpi_dev, "Failed to suspend APs\n");
|
2009-03-17 00:48:11 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-02-16 22:28:17 +00:00
|
|
|
WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0));
|
2009-03-23 22:35:30 +00:00
|
|
|
WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0));
|
2009-03-17 00:48:11 +00:00
|
|
|
|
2010-08-02 17:35:00 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_pcb, struct pcb *, susppcbs[0]);
|
Add support for the extended FPU states on amd64, both for native
64bit and 32bit ABIs. As a side-effect, it enables AVX on capable
CPUs.
In particular:
- Query the CPU support for XSAVE, list of the supported extensions
and the required size of FPU save area. The hw.use_xsave tunable is
provided for disabling XSAVE, and hw.xsave_mask may be used to
select the enabled extensions.
- Remove the FPU save area from PCB and dynamically allocate the
(run-time sized) user save area on the top of the kernel stack,
right above the PCB. Reorganize the thread0 PCB initialization to
postpone it after BSP is queried for save area size.
- The dumppcb, stoppcbs and susppcbs now do not carry the FPU state as
well. FPU state is only useful for suspend, where it is saved in
dynamically allocated suspfpusave area.
- Use XSAVE and XRSTOR to save/restore FPU state, if supported and
enabled.
- Define new mcontext_t flag _MC_HASFPXSTATE, indicating that
mcontext_t has a valid pointer to out-of-struct extended FPU
state. Signal handlers are supplied with stack-allocated fpu
state. The sigreturn(2) and setcontext(2) syscall honour the flag,
allowing the signal handlers to inspect and manipilate extended
state in the interrupted context.
- The getcontext(2) never returns extended state, since there is no
place in the fixed-sized mcontext_t to place variable-sized save
area. And, since mcontext_t is embedded into ucontext_t, makes it
impossible to fix in a reasonable way. Instead of extending
getcontext(2) syscall, provide a sysarch(2) facility to query
extended FPU state.
- Add ptrace(2) support for getting and setting extended state; while
there, implement missed PT_I386_{GET,SET}XMMREGS for 32bit binaries.
- Change fpu_kern KPI to not expose struct fpu_kern_ctx layout to
consumers, making it opaque. Internally, struct fpu_kern_ctx now
contains a space for the extended state. Convert in-kernel consumers
of fpu_kern KPI both on i386 and amd64.
First version of the support for AVX was submitted by Tim Bird
<tim.bird am sony com> on behalf of Sony. This version was written
from scratch.
Tested by: pho (previous version), Yamagi Burmeister <lists yamagi org>
MFC after: 1 month
2012-01-21 17:45:27 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_fpusave, void *, suspfpusave[0]);
|
2009-03-17 00:48:11 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_gdt, uint16_t,
|
2010-08-02 17:35:00 +00:00
|
|
|
susppcbs[0]->pcb_gdt.rd_limit);
|
2009-03-17 00:48:11 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t,
|
2010-08-02 17:35:00 +00:00
|
|
|
susppcbs[0]->pcb_gdt.rd_base);
|
2009-03-17 00:48:11 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_cpu, int, 0);
|
|
|
|
|
|
|
|
/* Call ACPICA to enter the desired sleep state */
|
|
|
|
if (state == ACPI_STATE_S4 && sc->acpi_s4bios)
|
|
|
|
status = AcpiEnterSleepStateS4bios();
|
|
|
|
else
|
2012-03-20 21:37:52 +00:00
|
|
|
status = AcpiEnterSleepState(state, acpi_sleep_flags);
|
2009-03-17 00:48:11 +00:00
|
|
|
|
|
|
|
if (status != AE_OK) {
|
|
|
|
device_printf(sc->acpi_dev,
|
|
|
|
"AcpiEnterSleepState failed - %s\n",
|
|
|
|
AcpiFormatException(status));
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
ia32_pause();
|
|
|
|
} else {
|
2010-11-23 16:12:35 +00:00
|
|
|
pmap_init_pat();
|
2012-02-15 23:33:22 +00:00
|
|
|
load_cr3(susppcbs[0]->pcb_cr3);
|
2012-03-30 17:03:06 +00:00
|
|
|
initializecpu();
|
2010-08-13 22:08:42 +00:00
|
|
|
PCPU_SET(switchtime, 0);
|
2010-08-12 00:20:46 +00:00
|
|
|
PCPU_SET(switchticks, ticks);
|
2009-03-17 00:48:11 +00:00
|
|
|
#ifdef SMP
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
if (!CPU_EMPTY(&wakeup_cpus))
|
|
|
|
acpi_wakeup_cpus(sc, &wakeup_cpus);
|
2009-03-17 00:48:11 +00:00
|
|
|
#endif
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
#ifdef SMP
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
if (!CPU_EMPTY(&wakeup_cpus))
|
2009-03-17 00:48:11 +00:00
|
|
|
restart_cpus(wakeup_cpus);
|
|
|
|
#endif
|
|
|
|
|
2010-06-15 18:51:41 +00:00
|
|
|
mca_resume();
|
2012-03-19 21:47:50 +00:00
|
|
|
intr_resume();
|
2012-03-20 20:37:23 +00:00
|
|
|
intr_restore(rf);
|
2009-03-17 00:48:11 +00:00
|
|
|
|
|
|
|
AcpiSetFirmwareWakingVector(0);
|
|
|
|
|
|
|
|
if (ret == 0 && mem_range_softc.mr_op != NULL &&
|
|
|
|
mem_range_softc.mr_op->reinit != NULL)
|
|
|
|
mem_range_softc.mr_op->reinit(&mem_range_softc);
|
|
|
|
|
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
2009-10-08 17:41:53 +00:00
|
|
|
static void *
|
2009-03-17 00:48:11 +00:00
|
|
|
acpi_alloc_wakeup_handler(void)
|
|
|
|
{
|
|
|
|
void *wakeaddr;
|
2009-11-04 22:39:18 +00:00
|
|
|
int i;
|
2009-03-17 00:48:11 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Specify the region for our wakeup code. We want it in the low 1 MB
|
2009-10-08 17:41:53 +00:00
|
|
|
* 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.
|
2009-03-17 00:48:11 +00:00
|
|
|
*/
|
2012-02-15 23:33:22 +00:00
|
|
|
wakeaddr = contigmalloc(4 * PAGE_SIZE, M_DEVBUF, M_WAITOK, 0x500,
|
2009-10-08 17:41:53 +00:00
|
|
|
0xa0000, PAGE_SIZE, 0ul);
|
2009-03-17 00:48:11 +00:00
|
|
|
if (wakeaddr == NULL) {
|
|
|
|
printf("%s: can't alloc wake memory\n", __func__);
|
2009-10-08 17:41:53 +00:00
|
|
|
return (NULL);
|
2009-03-17 00:48:11 +00:00
|
|
|
}
|
2012-02-16 22:28:17 +00:00
|
|
|
if (EVENTHANDLER_REGISTER(power_resume, acpi_stop_beep, NULL,
|
|
|
|
EVENTHANDLER_PRI_LAST) == NULL) {
|
|
|
|
printf("%s: can't register event handler\n", __func__);
|
|
|
|
contigfree(wakeaddr, 4 * PAGE_SIZE, M_DEVBUF);
|
|
|
|
return (NULL);
|
|
|
|
}
|
2010-08-02 17:35:00 +00:00
|
|
|
susppcbs = malloc(mp_ncpus * sizeof(*susppcbs), M_DEVBUF, M_WAITOK);
|
Add support for the extended FPU states on amd64, both for native
64bit and 32bit ABIs. As a side-effect, it enables AVX on capable
CPUs.
In particular:
- Query the CPU support for XSAVE, list of the supported extensions
and the required size of FPU save area. The hw.use_xsave tunable is
provided for disabling XSAVE, and hw.xsave_mask may be used to
select the enabled extensions.
- Remove the FPU save area from PCB and dynamically allocate the
(run-time sized) user save area on the top of the kernel stack,
right above the PCB. Reorganize the thread0 PCB initialization to
postpone it after BSP is queried for save area size.
- The dumppcb, stoppcbs and susppcbs now do not carry the FPU state as
well. FPU state is only useful for suspend, where it is saved in
dynamically allocated suspfpusave area.
- Use XSAVE and XRSTOR to save/restore FPU state, if supported and
enabled.
- Define new mcontext_t flag _MC_HASFPXSTATE, indicating that
mcontext_t has a valid pointer to out-of-struct extended FPU
state. Signal handlers are supplied with stack-allocated fpu
state. The sigreturn(2) and setcontext(2) syscall honour the flag,
allowing the signal handlers to inspect and manipilate extended
state in the interrupted context.
- The getcontext(2) never returns extended state, since there is no
place in the fixed-sized mcontext_t to place variable-sized save
area. And, since mcontext_t is embedded into ucontext_t, makes it
impossible to fix in a reasonable way. Instead of extending
getcontext(2) syscall, provide a sysarch(2) facility to query
extended FPU state.
- Add ptrace(2) support for getting and setting extended state; while
there, implement missed PT_I386_{GET,SET}XMMREGS for 32bit binaries.
- Change fpu_kern KPI to not expose struct fpu_kern_ctx layout to
consumers, making it opaque. Internally, struct fpu_kern_ctx now
contains a space for the extended state. Convert in-kernel consumers
of fpu_kern KPI both on i386 and amd64.
First version of the support for AVX was submitted by Tim Bird
<tim.bird am sony com> on behalf of Sony. This version was written
from scratch.
Tested by: pho (previous version), Yamagi Burmeister <lists yamagi org>
MFC after: 1 month
2012-01-21 17:45:27 +00:00
|
|
|
suspfpusave = malloc(mp_ncpus * sizeof(void *), M_DEVBUF, M_WAITOK);
|
|
|
|
for (i = 0; i < mp_ncpus; i++) {
|
2010-08-02 17:35:00 +00:00
|
|
|
susppcbs[i] = malloc(sizeof(**susppcbs), M_DEVBUF, M_WAITOK);
|
Add support for the extended FPU states on amd64, both for native
64bit and 32bit ABIs. As a side-effect, it enables AVX on capable
CPUs.
In particular:
- Query the CPU support for XSAVE, list of the supported extensions
and the required size of FPU save area. The hw.use_xsave tunable is
provided for disabling XSAVE, and hw.xsave_mask may be used to
select the enabled extensions.
- Remove the FPU save area from PCB and dynamically allocate the
(run-time sized) user save area on the top of the kernel stack,
right above the PCB. Reorganize the thread0 PCB initialization to
postpone it after BSP is queried for save area size.
- The dumppcb, stoppcbs and susppcbs now do not carry the FPU state as
well. FPU state is only useful for suspend, where it is saved in
dynamically allocated suspfpusave area.
- Use XSAVE and XRSTOR to save/restore FPU state, if supported and
enabled.
- Define new mcontext_t flag _MC_HASFPXSTATE, indicating that
mcontext_t has a valid pointer to out-of-struct extended FPU
state. Signal handlers are supplied with stack-allocated fpu
state. The sigreturn(2) and setcontext(2) syscall honour the flag,
allowing the signal handlers to inspect and manipilate extended
state in the interrupted context.
- The getcontext(2) never returns extended state, since there is no
place in the fixed-sized mcontext_t to place variable-sized save
area. And, since mcontext_t is embedded into ucontext_t, makes it
impossible to fix in a reasonable way. Instead of extending
getcontext(2) syscall, provide a sysarch(2) facility to query
extended FPU state.
- Add ptrace(2) support for getting and setting extended state; while
there, implement missed PT_I386_{GET,SET}XMMREGS for 32bit binaries.
- Change fpu_kern KPI to not expose struct fpu_kern_ctx layout to
consumers, making it opaque. Internally, struct fpu_kern_ctx now
contains a space for the extended state. Convert in-kernel consumers
of fpu_kern KPI both on i386 and amd64.
First version of the support for AVX was submitted by Tim Bird
<tim.bird am sony com> on behalf of Sony. This version was written
from scratch.
Tested by: pho (previous version), Yamagi Burmeister <lists yamagi org>
MFC after: 1 month
2012-01-21 17:45:27 +00:00
|
|
|
suspfpusave[i] = alloc_fpusave(M_WAITOK);
|
|
|
|
}
|
2001-07-20 06:07:34 +00:00
|
|
|
|
2009-10-08 17:41:53 +00:00
|
|
|
return (wakeaddr);
|
|
|
|
}
|
2009-03-17 00:48:11 +00:00
|
|
|
|
2001-07-20 06:07:34 +00:00
|
|
|
void
|
|
|
|
acpi_install_wakeup_handler(struct acpi_softc *sc)
|
|
|
|
{
|
2009-10-08 17:41:53 +00:00
|
|
|
static void *wakeaddr = NULL;
|
2009-03-17 00:48:11 +00:00
|
|
|
uint64_t *pt4, *pt3, *pt2;
|
|
|
|
int i;
|
|
|
|
|
2009-10-08 17:41:53 +00:00
|
|
|
if (wakeaddr != NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
wakeaddr = acpi_alloc_wakeup_handler();
|
|
|
|
if (wakeaddr == NULL)
|
2009-03-17 00:48:11 +00:00
|
|
|
return;
|
|
|
|
|
2009-10-08 17:41:53 +00:00
|
|
|
sc->acpi_wakeaddr = (vm_offset_t)wakeaddr;
|
|
|
|
sc->acpi_wakephys = vtophys(wakeaddr);
|
2009-03-17 00:48:11 +00:00
|
|
|
|
|
|
|
bcopy(wakecode, (void *)WAKECODE_VADDR(sc), sizeof(wakecode));
|
|
|
|
|
|
|
|
/* Patch GDT base address, ljmp targets and page table base address. */
|
|
|
|
WAKECODE_FIXUP((bootgdtdesc + 2), uint32_t,
|
|
|
|
WAKECODE_PADDR(sc) + bootgdt);
|
|
|
|
WAKECODE_FIXUP((wakeup_sw32 + 2), uint32_t,
|
|
|
|
WAKECODE_PADDR(sc) + wakeup_32);
|
|
|
|
WAKECODE_FIXUP((wakeup_sw64 + 1), uint32_t,
|
|
|
|
WAKECODE_PADDR(sc) + wakeup_64);
|
|
|
|
WAKECODE_FIXUP(wakeup_pagetables, uint32_t, sc->acpi_wakephys);
|
|
|
|
|
|
|
|
/* Save pointers to some global data. */
|
|
|
|
WAKECODE_FIXUP(wakeup_retaddr, void *, acpi_restorecpu);
|
|
|
|
WAKECODE_FIXUP(wakeup_kpml4, uint64_t, KPML4phys);
|
|
|
|
WAKECODE_FIXUP(wakeup_ctx, vm_offset_t,
|
|
|
|
WAKECODE_VADDR(sc) + wakeup_ctx);
|
|
|
|
WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER));
|
|
|
|
WAKECODE_FIXUP(wakeup_star, uint64_t, rdmsr(MSR_STAR));
|
|
|
|
WAKECODE_FIXUP(wakeup_lstar, uint64_t, rdmsr(MSR_LSTAR));
|
|
|
|
WAKECODE_FIXUP(wakeup_cstar, uint64_t, rdmsr(MSR_CSTAR));
|
|
|
|
WAKECODE_FIXUP(wakeup_sfmask, uint64_t, rdmsr(MSR_SF_MASK));
|
2012-01-31 17:51:30 +00:00
|
|
|
WAKECODE_FIXUP(wakeup_xsmask, uint64_t, xsave_mask);
|
2009-03-17 00:48:11 +00:00
|
|
|
|
|
|
|
/* Build temporary page tables below realmode code. */
|
2009-10-08 17:41:53 +00:00
|
|
|
pt4 = wakeaddr;
|
2009-03-17 00:48:11 +00:00
|
|
|
pt3 = pt4 + (PAGE_SIZE) / sizeof(uint64_t);
|
|
|
|
pt2 = pt3 + (PAGE_SIZE) / sizeof(uint64_t);
|
|
|
|
|
|
|
|
/* Create the initial 1GB replicated page tables */
|
|
|
|
for (i = 0; i < 512; i++) {
|
|
|
|
/*
|
|
|
|
* Each slot of the level 4 pages points
|
|
|
|
* to the same level 3 page
|
|
|
|
*/
|
|
|
|
pt4[i] = (uint64_t)(sc->acpi_wakephys + PAGE_SIZE);
|
|
|
|
pt4[i] |= PG_V | PG_RW | PG_U;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Each slot of the level 3 pages points
|
|
|
|
* to the same level 2 page
|
|
|
|
*/
|
|
|
|
pt3[i] = (uint64_t)(sc->acpi_wakephys + (2 * PAGE_SIZE));
|
|
|
|
pt3[i] |= PG_V | PG_RW | PG_U;
|
|
|
|
|
|
|
|
/* The level 2 page slots are mapped with 2MB pages for 1GB. */
|
|
|
|
pt2[i] = i * (2 * 1024 * 1024);
|
|
|
|
pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bootverbose)
|
|
|
|
device_printf(sc->acpi_dev, "wakeup code va %p pa %p\n",
|
|
|
|
(void *)sc->acpi_wakeaddr, (void *)sc->acpi_wakephys);
|
2001-07-20 06:07:34 +00:00
|
|
|
}
|