Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/acpica/acpi_wakeup.c
| Show First 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | |||||
| extern int acpi_resume_beep; | extern int acpi_resume_beep; | ||||
| extern int acpi_reset_video; | extern int acpi_reset_video; | ||||
| extern int acpi_susp_bounce; | extern int acpi_susp_bounce; | ||||
| extern struct susppcb **susppcbs; | extern struct susppcb **susppcbs; | ||||
| static cpuset_t suspcpus; | static cpuset_t suspcpus; | ||||
| static void acpi_stop_beep(void *, enum power_stype); | static void acpi_stop_beep(void *, enum power_stype); | ||||
| 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 *); | |||||
| #define ACPI_WAKEPT_PAGES 7 | #define ACPI_WAKEPT_PAGES 7 | ||||
| #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) | ||||
| Show All 35 Lines | |||||
| #define WARMBOOT_SEG (KERNBASE + 0x0469) | #define WARMBOOT_SEG (KERNBASE + 0x0469) | ||||
| #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_bios(struct acpi_softc *sc) | ||||
| { | { | ||||
| uint32_t mpbioswarmvec; | uint32_t mpbioswarmvec; | ||||
| int cpu; | int cpu; | ||||
| u_char mpbiosreason; | u_char mpbiosreason; | ||||
| if (!efi_boot) { | |||||
| /* 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' */ | ||||
| } | |||||
| /* 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]); | ||||
| } | } | ||||
| } | } | ||||
| if (!efi_boot) { | |||||
| /* 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); | ||||
| } | } | ||||
| static void | |||||
| acpi_wakeup_cpus_efi(struct acpi_softc *sc) | |||||
| { | |||||
| int cpu; | |||||
| /* Wake up each AP. */ | |||||
| for (cpu = 1; cpu < mp_ncpus; cpu++) { | |||||
| if (!CPU_ISSET(cpu, &suspcpus)) | |||||
| continue; | |||||
| if (acpi_wakeup_ap(sc, cpu) == 0) { | |||||
| panic("acpi_wakeup: failed to resume AP #%d (PHY #%d)", | |||||
| cpu, cpu_apic_ids[cpu]); | |||||
| } | } | ||||
| } | |||||
| } | |||||
| 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; | ||||
| struct pcpu *pc; | struct pcpu *pc; | ||||
| int i; | int i; | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | 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); | ||||
| lapic_xapic_mode(); | lapic_xapic_mode(); | ||||
| if (!CPU_EMPTY(&suspcpus)) | if (!CPU_EMPTY(&suspcpus)) { | ||||
| acpi_wakeup_cpus(sc); | if (efi_boot) | ||||
| acpi_wakeup_cpus_efi(sc); | |||||
| else | |||||
| acpi_wakeup_cpus_bios(sc); | |||||
| } | |||||
| } | } | ||||
| if (!CPU_EMPTY(&suspcpus)) | if (!CPU_EMPTY(&suspcpus)) | ||||
| resume_cpus(suspcpus); | resume_cpus(suspcpus); | ||||
| /* | /* | ||||
| * Re-read cpu_stdext_feature3, which was zeroed-out | * Re-read cpu_stdext_feature3, which was zeroed-out | ||||
| * in acpi_sleep_machdep(), after the microcode was | * in acpi_sleep_machdep(), after the microcode was | ||||
| ▲ Show 20 Lines • Show All 171 Lines • Show Last 20 Lines | |||||