Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/acpica/acpi_wakeup.c
- This file was copied from sys/x86/acpica/acpi_wakeup.c.
Show All 26 Lines | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * 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 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#if defined(__amd64__) | |||||
#define DEV_APIC | |||||
#else | |||||
#include "opt_apic.h" | |||||
#endif | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/eventhandler.h> | #include <sys/eventhandler.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/memrange.h> | #include <sys/memrange.h> | ||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/cons.h> | #include <sys/cons.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <machine/clock.h> | #include <machine/clock.h> | ||||
#include <machine/cpu.h> | #include <machine/cpu.h> | ||||
#include <machine/intr_machdep.h> | #include <machine/intr_machdep.h> | ||||
#include <machine/md_var.h> | #include <machine/md_var.h> | ||||
#include <x86/mca.h> | #include <x86/mca.h> | ||||
#include <machine/pcb.h> | #include <machine/pcb.h> | ||||
#include <machine/specialreg.h> | #include <machine/specialreg.h> | ||||
#include <x86/ucode.h> | #include <x86/ucode.h> | ||||
#ifdef DEV_APIC | |||||
#include <x86/apicreg.h> | #include <x86/apicreg.h> | ||||
#include <x86/apicvar.h> | #include <x86/apicvar.h> | ||||
#endif | |||||
#ifdef SMP | #ifdef SMP | ||||
#include <machine/smp.h> | #include <machine/smp.h> | ||||
#include <machine/vmparam.h> | #include <machine/vmparam.h> | ||||
#endif | #endif | ||||
#include <contrib/dev/acpica/include/acpi.h> | #include <contrib/dev/acpica/include/acpi.h> | ||||
#include <dev/acpica/acpivar.h> | #include <dev/acpica/acpivar.h> | ||||
Show All 18 Lines | |||||
static void *acpi_alloc_wakeup_handler(void **); | static void *acpi_alloc_wakeup_handler(void **); | ||||
static void acpi_stop_beep(void *); | static void acpi_stop_beep(void *); | ||||
#ifdef SMP | #ifdef SMP | ||||
static int acpi_wakeup_ap(struct acpi_softc *, int); | static int acpi_wakeup_ap(struct acpi_softc *, int); | ||||
static void acpi_wakeup_cpus(struct acpi_softc *); | static void acpi_wakeup_cpus(struct acpi_softc *); | ||||
#endif | #endif | ||||
#ifdef __amd64__ | |||||
#define ACPI_WAKEPAGES 8 | #define ACPI_WAKEPAGES 8 | ||||
#else | |||||
#define ACPI_WAKEPAGES 1 | |||||
#endif | |||||
#define WAKECODE_FIXUP(offset, type, val) do { \ | #define WAKECODE_FIXUP(offset, type, val) do { \ | ||||
type *addr; \ | type *addr; \ | ||||
addr = (type *)(sc->acpi_wakeaddr + (offset)); \ | addr = (type *)(sc->acpi_wakeaddr + (offset)); \ | ||||
*addr = val; \ | *addr = val; \ | ||||
} while (0) | } while (0) | ||||
static void | static void | ||||
Show All 25 Lines | for (ms = 0; ms < 5000; ms++) { | ||||
if (!CPU_ISSET(cpu, &suspended_cpus)) | if (!CPU_ISSET(cpu, &suspended_cpus)) | ||||
return (1); /* return SUCCESS */ | return (1); /* return SUCCESS */ | ||||
DELAY(1000); | DELAY(1000); | ||||
} | } | ||||
return (0); /* return FAILURE */ | return (0); /* return FAILURE */ | ||||
} | } | ||||
#define WARMBOOT_TARGET 0 | #define WARMBOOT_TARGET 0 | ||||
#ifdef __amd64__ | |||||
#define WARMBOOT_OFF (KERNBASE + 0x0467) | #define WARMBOOT_OFF (KERNBASE + 0x0467) | ||||
#define WARMBOOT_SEG (KERNBASE + 0x0469) | #define WARMBOOT_SEG (KERNBASE + 0x0469) | ||||
#else /* __i386__ */ | |||||
#define WARMBOOT_OFF (PMAP_MAP_LOW + 0x0467) | |||||
#define WARMBOOT_SEG (PMAP_MAP_LOW + 0x0469) | |||||
#endif | |||||
#define CMOS_REG (0x70) | #define CMOS_REG (0x70) | ||||
#define CMOS_DATA (0x71) | #define CMOS_DATA (0x71) | ||||
#define BIOS_RESET (0x0f) | #define BIOS_RESET (0x0f) | ||||
#define BIOS_WARM (0x0a) | #define BIOS_WARM (0x0a) | ||||
static void | static void | ||||
acpi_wakeup_cpus(struct acpi_softc *sc) | acpi_wakeup_cpus(struct acpi_softc *sc) | ||||
{ | { | ||||
uint32_t mpbioswarmvec; | uint32_t mpbioswarmvec; | ||||
int cpu; | int cpu; | ||||
u_char mpbiosreason; | u_char mpbiosreason; | ||||
#ifdef __amd64__ | |||||
if (!efi_boot) { | if (!efi_boot) { | ||||
#endif | |||||
/* save the current value of the warm-start vector */ | /* save the current value of the warm-start vector */ | ||||
mpbioswarmvec = *((uint32_t *)WARMBOOT_OFF); | mpbioswarmvec = *((uint32_t *)WARMBOOT_OFF); | ||||
outb(CMOS_REG, BIOS_RESET); | outb(CMOS_REG, BIOS_RESET); | ||||
mpbiosreason = inb(CMOS_DATA); | mpbiosreason = inb(CMOS_DATA); | ||||
/* setup a vector to our boot code */ | /* setup a vector to our boot code */ | ||||
*((volatile u_short *)WARMBOOT_OFF) = WARMBOOT_TARGET; | *((volatile u_short *)WARMBOOT_OFF) = WARMBOOT_TARGET; | ||||
*((volatile u_short *)WARMBOOT_SEG) = sc->acpi_wakephys >> 4; | *((volatile u_short *)WARMBOOT_SEG) = sc->acpi_wakephys >> 4; | ||||
outb(CMOS_REG, BIOS_RESET); | outb(CMOS_REG, BIOS_RESET); | ||||
outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ | outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ | ||||
#ifdef __amd64__ | |||||
} | } | ||||
#endif | |||||
/* Wake up each AP. */ | /* Wake up each AP. */ | ||||
for (cpu = 1; cpu < mp_ncpus; cpu++) { | for (cpu = 1; cpu < mp_ncpus; cpu++) { | ||||
if (!CPU_ISSET(cpu, &suspcpus)) | if (!CPU_ISSET(cpu, &suspcpus)) | ||||
continue; | continue; | ||||
if (acpi_wakeup_ap(sc, cpu) == 0) { | if (acpi_wakeup_ap(sc, cpu) == 0) { | ||||
/* restore the warmstart vector */ | /* restore the warmstart vector */ | ||||
*(uint32_t *)WARMBOOT_OFF = mpbioswarmvec; | *(uint32_t *)WARMBOOT_OFF = mpbioswarmvec; | ||||
panic("acpi_wakeup: failed to resume AP #%d (PHY #%d)", | panic("acpi_wakeup: failed to resume AP #%d (PHY #%d)", | ||||
cpu, cpu_apic_ids[cpu]); | cpu, cpu_apic_ids[cpu]); | ||||
} | } | ||||
} | } | ||||
#ifdef __i386__ | |||||
/* | |||||
* Remove the identity mapping of low memory for all CPUs and sync | |||||
* the TLB for the BSP. The APs are now spinning in | |||||
* cpususpend_handler() and we will release them soon. Then each | |||||
* will invalidate its TLB. | |||||
*/ | |||||
pmap_remap_lowptdi(false); | |||||
#endif | |||||
#ifdef __amd64__ | |||||
if (!efi_boot) { | if (!efi_boot) { | ||||
#endif | |||||
/* restore the warmstart vector */ | /* restore the warmstart vector */ | ||||
*(uint32_t *)WARMBOOT_OFF = mpbioswarmvec; | *(uint32_t *)WARMBOOT_OFF = mpbioswarmvec; | ||||
outb(CMOS_REG, BIOS_RESET); | outb(CMOS_REG, BIOS_RESET); | ||||
outb(CMOS_DATA, mpbiosreason); | outb(CMOS_DATA, mpbiosreason); | ||||
#ifdef __amd64__ | |||||
} | } | ||||
#endif | |||||
} | } | ||||
#endif | #endif | ||||
int | int | ||||
acpi_sleep_machdep(struct acpi_softc *sc, int state) | acpi_sleep_machdep(struct acpi_softc *sc, int state) | ||||
{ | { | ||||
ACPI_STATUS status; | ACPI_STATUS status; | ||||
struct pcb *pcb; | struct pcb *pcb; | ||||
#ifdef __amd64__ | |||||
struct pcpu *pc; | struct pcpu *pc; | ||||
int i; | int i; | ||||
#endif | |||||
if (sc->acpi_wakeaddr == 0ul) | if (sc->acpi_wakeaddr == 0ul) | ||||
return (-1); /* couldn't alloc wake memory */ | return (-1); /* couldn't alloc wake memory */ | ||||
#ifdef SMP | #ifdef SMP | ||||
suspcpus = all_cpus; | suspcpus = all_cpus; | ||||
CPU_CLR(PCPU_GET(cpuid), &suspcpus); | CPU_CLR(PCPU_GET(cpuid), &suspcpus); | ||||
#endif | #endif | ||||
if (acpi_resume_beep != 0) | if (acpi_resume_beep != 0) | ||||
timer_spkr_acquire(); | timer_spkr_acquire(); | ||||
AcpiSetFirmwareWakingVector(sc->acpi_wakephys, 0); | AcpiSetFirmwareWakingVector(sc->acpi_wakephys, 0); | ||||
intr_suspend(); | intr_suspend(); | ||||
pcb = &susppcbs[0]->sp_pcb; | pcb = &susppcbs[0]->sp_pcb; | ||||
if (savectx(pcb)) { | if (savectx(pcb)) { | ||||
#ifdef __amd64__ | |||||
fpususpend(susppcbs[0]->sp_fpususpend); | fpususpend(susppcbs[0]->sp_fpususpend); | ||||
#else | |||||
npxsuspend(susppcbs[0]->sp_fpususpend); | |||||
#endif | |||||
#ifdef SMP | #ifdef SMP | ||||
if (!CPU_EMPTY(&suspcpus) && suspend_cpus(suspcpus) == 0) { | if (!CPU_EMPTY(&suspcpus) && suspend_cpus(suspcpus) == 0) { | ||||
device_printf(sc->acpi_dev, "Failed to suspend APs\n"); | device_printf(sc->acpi_dev, "Failed to suspend APs\n"); | ||||
return (0); /* couldn't sleep */ | return (0); /* couldn't sleep */ | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef __amd64__ | |||||
hw_ibrs_ibpb_active = 0; | hw_ibrs_ibpb_active = 0; | ||||
hw_ssb_active = 0; | hw_ssb_active = 0; | ||||
cpu_stdext_feature3 = 0; | cpu_stdext_feature3 = 0; | ||||
CPU_FOREACH(i) { | CPU_FOREACH(i) { | ||||
pc = pcpu_find(i); | pc = pcpu_find(i); | ||||
pc->pc_ibpb_set = 0; | pc->pc_ibpb_set = 0; | ||||
} | } | ||||
#endif | |||||
WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0)); | WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0)); | ||||
WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0)); | WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0)); | ||||
#ifdef __amd64__ | |||||
WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER) & | WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER) & | ||||
~(EFER_LMA)); | ~(EFER_LMA)); | ||||
#else | |||||
if ((amd_feature & AMDID_NX) != 0) | |||||
WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER)); | |||||
WAKECODE_FIXUP(wakeup_cr4, register_t, pcb->pcb_cr4); | |||||
#endif | |||||
WAKECODE_FIXUP(wakeup_pcb, struct pcb *, pcb); | WAKECODE_FIXUP(wakeup_pcb, struct pcb *, pcb); | ||||
WAKECODE_FIXUP(wakeup_gdt, uint16_t, pcb->pcb_gdt.rd_limit); | WAKECODE_FIXUP(wakeup_gdt, uint16_t, pcb->pcb_gdt.rd_limit); | ||||
WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t, pcb->pcb_gdt.rd_base); | WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t, pcb->pcb_gdt.rd_base); | ||||
#ifdef __i386__ | |||||
/* | |||||
* Map some low memory with virt == phys for ACPI wakecode | |||||
* to use to jump to high memory after enabling paging. This | |||||
* is the same as for similar jump in locore, except the | |||||
* jump is a single instruction, and we know its address | |||||
* more precisely so only need a single PTD, and we have to | |||||
* be careful to use the kernel map (PTD[0] is for curthread | |||||
* which may be a user thread in deprecated APIs). | |||||
*/ | |||||
pmap_remap_lowptdi(true); | |||||
#endif | |||||
/* Call ACPICA to enter the desired sleep state */ | /* Call ACPICA to enter the desired sleep state */ | ||||
if (state == ACPI_STATE_S4 && sc->acpi_s4bios) | if (state == ACPI_STATE_S4 && sc->acpi_s4bios) | ||||
status = AcpiEnterSleepStateS4bios(); | status = AcpiEnterSleepStateS4bios(); | ||||
else | else | ||||
status = AcpiEnterSleepState(state); | status = AcpiEnterSleepState(state); | ||||
if (ACPI_FAILURE(status)) { | if (ACPI_FAILURE(status)) { | ||||
device_printf(sc->acpi_dev, | device_printf(sc->acpi_dev, | ||||
"AcpiEnterSleepState failed - %s\n", | "AcpiEnterSleepState failed - %s\n", | ||||
AcpiFormatException(status)); | AcpiFormatException(status)); | ||||
return (0); /* couldn't sleep */ | return (0); /* couldn't sleep */ | ||||
} | } | ||||
if (acpi_susp_bounce) | if (acpi_susp_bounce) | ||||
resumectx(pcb); | resumectx(pcb); | ||||
for (;;) | for (;;) | ||||
ia32_pause(); | ia32_pause(); | ||||
} else { | } else { | ||||
/* | /* | ||||
* Re-initialize console hardware as soon as possibe. | * Re-initialize console hardware as soon as possibe. | ||||
* No console output (e.g. printf) is allowed before | * No console output (e.g. printf) is allowed before | ||||
* this point. | * this point. | ||||
*/ | */ | ||||
cnresume(); | cnresume(); | ||||
#ifdef __amd64__ | |||||
fpuresume(susppcbs[0]->sp_fpususpend); | fpuresume(susppcbs[0]->sp_fpususpend); | ||||
#else | |||||
npxresume(susppcbs[0]->sp_fpususpend); | |||||
#endif | |||||
} | } | ||||
return (1); /* wakeup successfully */ | return (1); /* wakeup successfully */ | ||||
} | } | ||||
int | int | ||||
acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result, | acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result, | ||||
int intr_enabled) | int intr_enabled) | ||||
{ | { | ||||
if (sleep_result == -1) | if (sleep_result == -1) | ||||
return (sleep_result); | return (sleep_result); | ||||
if (!intr_enabled) { | if (!intr_enabled) { | ||||
/* Wakeup MD procedures in interrupt disabled context */ | /* Wakeup MD procedures in interrupt disabled context */ | ||||
if (sleep_result == 1) { | if (sleep_result == 1) { | ||||
ucode_reload(); | ucode_reload(); | ||||
pmap_init_pat(); | pmap_init_pat(); | ||||
initializecpu(); | initializecpu(); | ||||
PCPU_SET(switchtime, 0); | PCPU_SET(switchtime, 0); | ||||
PCPU_SET(switchticks, ticks); | PCPU_SET(switchticks, ticks); | ||||
#ifdef DEV_APIC | |||||
lapic_xapic_mode(); | lapic_xapic_mode(); | ||||
#endif | |||||
#ifdef SMP | #ifdef SMP | ||||
if (!CPU_EMPTY(&suspcpus)) | if (!CPU_EMPTY(&suspcpus)) | ||||
acpi_wakeup_cpus(sc); | acpi_wakeup_cpus(sc); | ||||
#endif | #endif | ||||
} | } | ||||
#ifdef SMP | #ifdef SMP | ||||
if (!CPU_EMPTY(&suspcpus)) | if (!CPU_EMPTY(&suspcpus)) | ||||
resume_cpus(suspcpus); | resume_cpus(suspcpus); | ||||
#endif | #endif | ||||
mca_resume(); | mca_resume(); | ||||
#ifdef __amd64__ | |||||
if (vmm_resume_p != NULL) | if (vmm_resume_p != NULL) | ||||
vmm_resume_p(); | vmm_resume_p(); | ||||
#endif | |||||
intr_resume(/*suspend_cancelled*/false); | intr_resume(/*suspend_cancelled*/false); | ||||
AcpiSetFirmwareWakingVector(0, 0); | AcpiSetFirmwareWakingVector(0, 0); | ||||
} else { | } else { | ||||
/* Wakeup MD procedures in interrupt enabled context */ | /* Wakeup MD procedures in interrupt enabled context */ | ||||
if (sleep_result == 1 && mem_range_softc.mr_op != NULL && | if (sleep_result == 1 && mem_range_softc.mr_op != NULL && | ||||
mem_range_softc.mr_op->reinit != NULL) | mem_range_softc.mr_op->reinit != NULL) | ||||
mem_range_softc.mr_op->reinit(&mem_range_softc); | mem_range_softc.mr_op->reinit(&mem_range_softc); | ||||
Show All 13 Lines | acpi_alloc_wakeup_handler(void *wakepages[ACPI_WAKEPAGES]) | ||||
* Specify the region for our wakeup code. We want it in the low 1 MB | * Specify the region for our wakeup code. We want it in the low 1 MB | ||||
* region, excluding real mode IVT (0-0x3ff), BDA (0x400-0x4ff), EBDA | * region, excluding real mode IVT (0-0x3ff), BDA (0x400-0x4ff), EBDA | ||||
* (less than 128KB, below 0xa0000, must be excluded by SMAP and DSDT), | * (less than 128KB, below 0xa0000, must be excluded by SMAP and DSDT), | ||||
* and ROM area (0xa0000 and above). The temporary page tables must be | * and ROM area (0xa0000 and above). The temporary page tables must be | ||||
* page-aligned. | * page-aligned. | ||||
*/ | */ | ||||
for (i = 0; i < ACPI_WAKEPAGES; i++) { | for (i = 0; i < ACPI_WAKEPAGES; i++) { | ||||
wakepages[i] = contigmalloc(PAGE_SIZE, M_DEVBUF, | wakepages[i] = contigmalloc(PAGE_SIZE, M_DEVBUF, | ||||
M_NOWAIT | M_NOWAIT, 0x500, 0xa0000, PAGE_SIZE, 0ul); | ||||
#ifdef __i386__ | |||||
| M_EXEC | |||||
#endif | |||||
, 0x500, 0xa0000, PAGE_SIZE, 0ul); | |||||
if (wakepages[i] == NULL) { | if (wakepages[i] == NULL) { | ||||
printf("%s: can't alloc wake memory\n", __func__); | printf("%s: can't alloc wake memory\n", __func__); | ||||
goto freepages; | goto freepages; | ||||
} | } | ||||
} | } | ||||
if (EVENTHANDLER_REGISTER(power_resume, acpi_stop_beep, NULL, | if (EVENTHANDLER_REGISTER(power_resume, acpi_stop_beep, NULL, | ||||
EVENTHANDLER_PRI_LAST) == NULL) { | EVENTHANDLER_PRI_LAST) == NULL) { | ||||
printf("%s: can't register event handler\n", __func__); | printf("%s: can't register event handler\n", __func__); | ||||
goto freepages; | goto freepages; | ||||
} | } | ||||
susppcbs = malloc(mp_ncpus * sizeof(*susppcbs), M_DEVBUF, M_WAITOK); | susppcbs = malloc(mp_ncpus * sizeof(*susppcbs), M_DEVBUF, M_WAITOK); | ||||
markj: Shouldn't it be `i = 0`? | |||||
for (i = 0; i < mp_ncpus; i++) { | for (i = 0; i < mp_ncpus; i++) { | ||||
susppcbs[i] = malloc(sizeof(**susppcbs), M_DEVBUF, M_WAITOK); | susppcbs[i] = malloc(sizeof(**susppcbs), M_DEVBUF, M_WAITOK); | ||||
susppcbs[i]->sp_fpususpend = alloc_fpusave(M_WAITOK); | susppcbs[i]->sp_fpususpend = alloc_fpusave(M_WAITOK); | ||||
} | } | ||||
return (wakepages); | return (wakepages); | ||||
freepages: | freepages: | ||||
for (i = 0; i < ACPI_WAKEPAGES; i++) | for (i = 0; i < ACPI_WAKEPAGES; i++) | ||||
if (wakepages[i] != NULL) | if (wakepages[i] != NULL) | ||||
contigfree(wakepages[i], PAGE_SIZE, M_DEVBUF); | contigfree(wakepages[i], PAGE_SIZE, M_DEVBUF); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
void | void | ||||
acpi_install_wakeup_handler(struct acpi_softc *sc) | acpi_install_wakeup_handler(struct acpi_softc *sc) | ||||
{ | { | ||||
static void *wakeaddr; | static void *wakeaddr; | ||||
void *wakepages[ACPI_WAKEPAGES]; | void *wakepages[ACPI_WAKEPAGES]; | ||||
#ifdef __amd64__ | |||||
uint64_t *pt5, *pt4, *pt3, *pt2_0, *pt2_1, *pt2_2, *pt2_3; | uint64_t *pt5, *pt4, *pt3, *pt2_0, *pt2_1, *pt2_2, *pt2_3; | ||||
vm_paddr_t pt5pa, pt4pa, pt3pa, pt2_0pa, pt2_1pa, pt2_2pa, pt2_3pa; | vm_paddr_t pt5pa, pt4pa, pt3pa, pt2_0pa, pt2_1pa, pt2_2pa, pt2_3pa; | ||||
int i; | int i; | ||||
#endif | |||||
if (wakeaddr != NULL) | if (wakeaddr != NULL) | ||||
return; | return; | ||||
if (acpi_alloc_wakeup_handler(wakepages) == NULL) | if (acpi_alloc_wakeup_handler(wakepages) == NULL) | ||||
return; | return; | ||||
wakeaddr = wakepages[0]; | wakeaddr = wakepages[0]; | ||||
sc->acpi_wakeaddr = (vm_offset_t)wakeaddr; | sc->acpi_wakeaddr = (vm_offset_t)wakeaddr; | ||||
sc->acpi_wakephys = vtophys(wakeaddr); | sc->acpi_wakephys = vtophys(wakeaddr); | ||||
#ifdef __amd64__ | |||||
if (la57) { | if (la57) { | ||||
pt5 = wakepages[7]; | pt5 = wakepages[7]; | ||||
pt5pa = vtophys(pt5); | pt5pa = vtophys(pt5); | ||||
} | } | ||||
pt4 = wakepages[1]; | pt4 = wakepages[1]; | ||||
pt3 = wakepages[2]; | pt3 = wakepages[2]; | ||||
pt2_0 = wakepages[3]; | pt2_0 = wakepages[3]; | ||||
pt2_1 = wakepages[4]; | pt2_1 = wakepages[4]; | ||||
pt2_2 = wakepages[5]; | pt2_2 = wakepages[5]; | ||||
pt2_3 = wakepages[6]; | pt2_3 = wakepages[6]; | ||||
pt4pa = vtophys(pt4); | pt4pa = vtophys(pt4); | ||||
pt3pa = vtophys(pt3); | pt3pa = vtophys(pt3); | ||||
pt2_0pa = vtophys(pt2_0); | pt2_0pa = vtophys(pt2_0); | ||||
pt2_1pa = vtophys(pt2_1); | pt2_1pa = vtophys(pt2_1); | ||||
pt2_2pa = vtophys(pt2_2); | pt2_2pa = vtophys(pt2_2); | ||||
pt2_3pa = vtophys(pt2_3); | pt2_3pa = vtophys(pt2_3); | ||||
#endif | |||||
bcopy(wakecode, (void *)sc->acpi_wakeaddr, sizeof(wakecode)); | bcopy(wakecode, (void *)sc->acpi_wakeaddr, sizeof(wakecode)); | ||||
/* Patch GDT base address, ljmp targets. */ | /* Patch GDT base address, ljmp targets. */ | ||||
WAKECODE_FIXUP((bootgdtdesc + 2), uint32_t, | WAKECODE_FIXUP((bootgdtdesc + 2), uint32_t, | ||||
sc->acpi_wakephys + bootgdt); | sc->acpi_wakephys + bootgdt); | ||||
WAKECODE_FIXUP((wakeup_sw32 + 2), uint32_t, | WAKECODE_FIXUP((wakeup_sw32 + 2), uint32_t, | ||||
sc->acpi_wakephys + wakeup_32); | sc->acpi_wakephys + wakeup_32); | ||||
#ifdef __amd64__ | |||||
WAKECODE_FIXUP((wakeup_sw64 + 1), uint32_t, | WAKECODE_FIXUP((wakeup_sw64 + 1), uint32_t, | ||||
sc->acpi_wakephys + wakeup_64); | sc->acpi_wakephys + wakeup_64); | ||||
WAKECODE_FIXUP(wakeup_pagetables, uint32_t, la57 ? (pt5pa | 0x1) : | WAKECODE_FIXUP(wakeup_pagetables, uint32_t, la57 ? (pt5pa | 0x1) : | ||||
pt4pa); | pt4pa); | ||||
#endif | |||||
/* Save pointers to some global data. */ | /* Save pointers to some global data. */ | ||||
WAKECODE_FIXUP(wakeup_ret, void *, resumectx); | WAKECODE_FIXUP(wakeup_ret, void *, resumectx); | ||||
#ifndef __amd64__ | |||||
WAKECODE_FIXUP(wakeup_cr3, register_t, pmap_get_kcr3()); | |||||
#else /* __amd64__ */ | |||||
/* Create 1:1 mapping for the low 4G */ | /* Create 1:1 mapping for the low 4G */ | ||||
if (la57) { | if (la57) { | ||||
bcopy(kernel_pmap->pm_pmltop, pt5, PAGE_SIZE); | bcopy(kernel_pmap->pm_pmltop, pt5, PAGE_SIZE); | ||||
pt5[0] = (uint64_t)pt4pa; | pt5[0] = (uint64_t)pt4pa; | ||||
pt5[0] |= PG_V | PG_RW | PG_U; | pt5[0] |= PG_V | PG_RW | PG_U; | ||||
} else { | } else { | ||||
bcopy(kernel_pmap->pm_pmltop, pt4, PAGE_SIZE); | bcopy(kernel_pmap->pm_pmltop, pt4, PAGE_SIZE); | ||||
} | } | ||||
Show All 21 Lines | acpi_install_wakeup_handler(struct acpi_softc *sc) | ||||
for (i = 0; i < NPDEPG; i++) { | for (i = 0; i < NPDEPG; i++) { | ||||
pt2_2[i] = (pd_entry_t)2 * NBPDP + i * NBPDR; | pt2_2[i] = (pd_entry_t)2 * NBPDP + i * NBPDR; | ||||
pt2_2[i] |= PG_V | PG_RW | PG_PS | PG_U; | pt2_2[i] |= PG_V | PG_RW | PG_PS | PG_U; | ||||
} | } | ||||
for (i = 0; i < NPDEPG; i++) { | for (i = 0; i < NPDEPG; i++) { | ||||
pt2_3[i] = (pd_entry_t)3 * NBPDP + i * NBPDR; | pt2_3[i] = (pd_entry_t)3 * NBPDP + i * NBPDR; | ||||
pt2_3[i] |= PG_V | PG_RW | PG_PS | PG_U; | pt2_3[i] |= PG_V | PG_RW | PG_PS | PG_U; | ||||
} | } | ||||
#endif /* !__amd64__ */ | |||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(sc->acpi_dev, "wakeup code va %#jx pa %#jx\n", | device_printf(sc->acpi_dev, "wakeup code va %#jx pa %#jx\n", | ||||
(uintmax_t)sc->acpi_wakeaddr, (uintmax_t)sc->acpi_wakephys); | (uintmax_t)sc->acpi_wakeaddr, (uintmax_t)sc->acpi_wakephys); | ||||
} | } |
Shouldn't it be i = 0?