1236772Siwasaki/*-
2236772Siwasaki * Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org>
3236772Siwasaki * Copyright (c) 2001-2012 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
4236772Siwasaki * Copyright (c) 2003 Peter Wemm
5236772Siwasaki * Copyright (c) 2008-2012 Jung-uk Kim <jkim@FreeBSD.org>
6236772Siwasaki * All rights reserved.
7236772Siwasaki *
8236772Siwasaki * Redistribution and use in source and binary forms, with or without
9236772Siwasaki * modification, are permitted provided that the following conditions
10236772Siwasaki * are met:
11236772Siwasaki * 1. Redistributions of source code must retain the above copyright
12236772Siwasaki *    notice, this list of conditions and the following disclaimer.
13236772Siwasaki * 2. Redistributions in binary form must reproduce the above copyright
14236772Siwasaki *    notice, this list of conditions and the following disclaimer in the
15236772Siwasaki *    documentation and/or other materials provided with the distribution.
16236772Siwasaki *
17236772Siwasaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18236772Siwasaki * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19236772Siwasaki * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20236772Siwasaki * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21236772Siwasaki * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22236772Siwasaki * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23236772Siwasaki * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24236772Siwasaki * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25236772Siwasaki * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26236772Siwasaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27236772Siwasaki * SUCH DAMAGE.
28236772Siwasaki */
29236772Siwasaki
30236772Siwasaki#include <sys/cdefs.h>
31236772Siwasaki__FBSDID("$FreeBSD: stable/11/sys/x86/acpica/acpi_wakeup.c 358582 2020-03-03 15:12:00Z kib $");
32236772Siwasaki
33279079Stijl#if defined(__amd64__)
34279079Stijl#define DEV_APIC
35279079Stijl#else
36279079Stijl#include "opt_apic.h"
37279079Stijl#endif
38270850Sjhb
39236772Siwasaki#include <sys/param.h>
40236772Siwasaki#include <sys/bus.h>
41236772Siwasaki#include <sys/eventhandler.h>
42236772Siwasaki#include <sys/kernel.h>
43236772Siwasaki#include <sys/malloc.h>
44236772Siwasaki#include <sys/memrange.h>
45236772Siwasaki#include <sys/smp.h>
46259823Sjhb#include <sys/systm.h>
47335659Savg#include <sys/cons.h>
48236772Siwasaki
49236772Siwasaki#include <vm/vm.h>
50236772Siwasaki#include <vm/pmap.h>
51236772Siwasaki
52236772Siwasaki#include <machine/clock.h>
53259782Sjhb#include <machine/cpu.h>
54236772Siwasaki#include <machine/intr_machdep.h>
55347700Smarkj#include <machine/md_var.h>
56236772Siwasaki#include <x86/mca.h>
57236772Siwasaki#include <machine/pcb.h>
58236772Siwasaki#include <machine/specialreg.h>
59347700Smarkj#include <x86/ucode.h>
60236772Siwasaki
61279079Stijl#ifdef DEV_APIC
62278954Skib#include <x86/apicreg.h>
63278954Skib#include <x86/apicvar.h>
64279079Stijl#endif
65236772Siwasaki#ifdef SMP
66236772Siwasaki#include <machine/smp.h>
67236772Siwasaki#include <machine/vmparam.h>
68236772Siwasaki#endif
69236772Siwasaki
70236772Siwasaki#include <contrib/dev/acpica/include/acpi.h>
71236772Siwasaki
72236772Siwasaki#include <dev/acpica/acpivar.h>
73236772Siwasaki
74236772Siwasaki#include "acpi_wakecode.h"
75236772Siwasaki#include "acpi_wakedata.h"
76236772Siwasaki
77236772Siwasaki/* Make sure the code is less than a page and leave room for the stack. */
78236772SiwasakiCTASSERT(sizeof(wakecode) < PAGE_SIZE - 1024);
79236772Siwasaki
80236772Siwasakiextern int		acpi_resume_beep;
81236772Siwasakiextern int		acpi_reset_video;
82335554Savgextern int		acpi_susp_bounce;
83236772Siwasaki
84236772Siwasaki#ifdef SMP
85271192Sjhbextern struct susppcb	**susppcbs;
86236772Siwasakistatic cpuset_t		suspcpus;
87236772Siwasaki#else
88271192Sjhbstatic struct susppcb	**susppcbs;
89236772Siwasaki#endif
90236772Siwasaki
91313128Smarkjstatic void		*acpi_alloc_wakeup_handler(void **);
92236772Siwasakistatic void		acpi_stop_beep(void *);
93236772Siwasaki
94236772Siwasaki#ifdef SMP
95236772Siwasakistatic int		acpi_wakeup_ap(struct acpi_softc *, int);
96236772Siwasakistatic void		acpi_wakeup_cpus(struct acpi_softc *);
97236772Siwasaki#endif
98236772Siwasaki
99236772Siwasaki#ifdef __amd64__
100313128Smarkj#define	ACPI_WAKEPAGES	4
101236772Siwasaki#else
102313128Smarkj#define	ACPI_WAKEPAGES	1
103236772Siwasaki#endif
104236772Siwasaki
105237037Sjkim#define	WAKECODE_FIXUP(offset, type, val)	do {	\
106236772Siwasaki	type	*addr;					\
107313128Smarkj	addr = (type *)(sc->acpi_wakeaddr + (offset));	\
108236772Siwasaki	*addr = val;					\
109236772Siwasaki} while (0)
110236772Siwasaki
111236772Siwasakistatic void
112236772Siwasakiacpi_stop_beep(void *arg)
113236772Siwasaki{
114236772Siwasaki
115236772Siwasaki	if (acpi_resume_beep != 0)
116236772Siwasaki		timer_spkr_release();
117236772Siwasaki}
118236772Siwasaki
119236772Siwasaki#ifdef SMP
120236772Siwasakistatic int
121236772Siwasakiacpi_wakeup_ap(struct acpi_softc *sc, int cpu)
122236772Siwasaki{
123271192Sjhb	struct pcb *pcb;
124313128Smarkj	int		vector = (sc->acpi_wakephys >> 12) & 0xff;
125236772Siwasaki	int		apic_id = cpu_apic_ids[cpu];
126236772Siwasaki	int		ms;
127236772Siwasaki
128271192Sjhb	pcb = &susppcbs[cpu]->sp_pcb;
129271192Sjhb	WAKECODE_FIXUP(wakeup_pcb, struct pcb *, pcb);
130271192Sjhb	WAKECODE_FIXUP(wakeup_gdt, uint16_t, pcb->pcb_gdt.rd_limit);
131271192Sjhb	WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t, pcb->pcb_gdt.rd_base);
132236772Siwasaki
133236938Siwasaki	ipi_startup(apic_id, vector);
134236772Siwasaki
135236772Siwasaki	/* Wait up to 5 seconds for it to resume. */
136236772Siwasaki	for (ms = 0; ms < 5000; ms++) {
137236772Siwasaki		if (!CPU_ISSET(cpu, &suspended_cpus))
138236772Siwasaki			return (1);	/* return SUCCESS */
139236772Siwasaki		DELAY(1000);
140236772Siwasaki	}
141236772Siwasaki	return (0);		/* return FAILURE */
142236772Siwasaki}
143236772Siwasaki
144236772Siwasaki#define	WARMBOOT_TARGET		0
145236772Siwasaki#define	WARMBOOT_OFF		(KERNBASE + 0x0467)
146236772Siwasaki#define	WARMBOOT_SEG		(KERNBASE + 0x0469)
147236772Siwasaki
148236772Siwasaki#define	CMOS_REG		(0x70)
149236772Siwasaki#define	CMOS_DATA		(0x71)
150236772Siwasaki#define	BIOS_RESET		(0x0f)
151236772Siwasaki#define	BIOS_WARM		(0x0a)
152236772Siwasaki
153236772Siwasakistatic void
154236772Siwasakiacpi_wakeup_cpus(struct acpi_softc *sc)
155236772Siwasaki{
156236772Siwasaki	uint32_t	mpbioswarmvec;
157236772Siwasaki	int		cpu;
158236772Siwasaki	u_char		mpbiosreason;
159236772Siwasaki
160236772Siwasaki	/* save the current value of the warm-start vector */
161236772Siwasaki	mpbioswarmvec = *((uint32_t *)WARMBOOT_OFF);
162236772Siwasaki	outb(CMOS_REG, BIOS_RESET);
163236772Siwasaki	mpbiosreason = inb(CMOS_DATA);
164236772Siwasaki
165236772Siwasaki	/* setup a vector to our boot code */
166236772Siwasaki	*((volatile u_short *)WARMBOOT_OFF) = WARMBOOT_TARGET;
167313128Smarkj	*((volatile u_short *)WARMBOOT_SEG) = sc->acpi_wakephys >> 4;
168236772Siwasaki	outb(CMOS_REG, BIOS_RESET);
169236772Siwasaki	outb(CMOS_DATA, BIOS_WARM);	/* 'warm-start' */
170236772Siwasaki
171236772Siwasaki	/* Wake up each AP. */
172236772Siwasaki	for (cpu = 1; cpu < mp_ncpus; cpu++) {
173236772Siwasaki		if (!CPU_ISSET(cpu, &suspcpus))
174236772Siwasaki			continue;
175236772Siwasaki		if (acpi_wakeup_ap(sc, cpu) == 0) {
176236772Siwasaki			/* restore the warmstart vector */
177236772Siwasaki			*(uint32_t *)WARMBOOT_OFF = mpbioswarmvec;
178236772Siwasaki			panic("acpi_wakeup: failed to resume AP #%d (PHY #%d)",
179236772Siwasaki			    cpu, cpu_apic_ids[cpu]);
180236772Siwasaki		}
181236772Siwasaki	}
182236772Siwasaki
183236772Siwasaki	/* restore the warmstart vector */
184236772Siwasaki	*(uint32_t *)WARMBOOT_OFF = mpbioswarmvec;
185236772Siwasaki
186236772Siwasaki	outb(CMOS_REG, BIOS_RESET);
187236772Siwasaki	outb(CMOS_DATA, mpbiosreason);
188236772Siwasaki}
189236772Siwasaki#endif
190236772Siwasaki
191236772Siwasakiint
192236772Siwasakiacpi_sleep_machdep(struct acpi_softc *sc, int state)
193236772Siwasaki{
194236772Siwasaki	ACPI_STATUS	status;
195271192Sjhb	struct pcb	*pcb;
196333361Skib#ifdef __amd64__
197333361Skib	struct pcpu *pc;
198333361Skib	int i;
199333361Skib#endif
200236772Siwasaki
201236772Siwasaki	if (sc->acpi_wakeaddr == 0ul)
202236772Siwasaki		return (-1);	/* couldn't alloc wake memory */
203236772Siwasaki
204236772Siwasaki#ifdef SMP
205236772Siwasaki	suspcpus = all_cpus;
206236772Siwasaki	CPU_CLR(PCPU_GET(cpuid), &suspcpus);
207236772Siwasaki#endif
208236772Siwasaki
209236772Siwasaki	if (acpi_resume_beep != 0)
210236772Siwasaki		timer_spkr_acquire();
211236772Siwasaki
212313128Smarkj	AcpiSetFirmwareWakingVector(sc->acpi_wakephys, 0);
213236772Siwasaki
214236772Siwasaki	intr_suspend();
215236772Siwasaki
216271192Sjhb	pcb = &susppcbs[0]->sp_pcb;
217271192Sjhb	if (savectx(pcb)) {
218236772Siwasaki#ifdef __amd64__
219271192Sjhb		fpususpend(susppcbs[0]->sp_fpususpend);
220314210Skib#else
221273995Sjhb		npxsuspend(susppcbs[0]->sp_fpususpend);
222236772Siwasaki#endif
223236772Siwasaki#ifdef SMP
224236772Siwasaki		if (!CPU_EMPTY(&suspcpus) && suspend_cpus(suspcpus) == 0) {
225236772Siwasaki			device_printf(sc->acpi_dev, "Failed to suspend APs\n");
226236772Siwasaki			return (0);	/* couldn't sleep */
227236772Siwasaki		}
228236772Siwasaki#endif
229333361Skib#ifdef __amd64__
230358582Skib		hw_ibrs_ibpb_active = 0;
231334152Skib		hw_ssb_active = 0;
232333361Skib		cpu_stdext_feature3 = 0;
233333361Skib		CPU_FOREACH(i) {
234333361Skib			pc = pcpu_find(i);
235333361Skib			pc->pc_ibpb_set = 0;
236333361Skib		}
237333361Skib#endif
238236772Siwasaki
239236772Siwasaki		WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0));
240236772Siwasaki		WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0));
241236772Siwasaki
242319133Skib#ifdef __amd64__
243319937Skib		WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER) &
244319937Skib		    ~(EFER_LMA));
245319133Skib#else
246271192Sjhb		WAKECODE_FIXUP(wakeup_cr4, register_t, pcb->pcb_cr4);
247237037Sjkim#endif
248271192Sjhb		WAKECODE_FIXUP(wakeup_pcb, struct pcb *, pcb);
249271192Sjhb		WAKECODE_FIXUP(wakeup_gdt, uint16_t, pcb->pcb_gdt.rd_limit);
250271192Sjhb		WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t, pcb->pcb_gdt.rd_base);
251236772Siwasaki
252236772Siwasaki		/* Call ACPICA to enter the desired sleep state */
253236772Siwasaki		if (state == ACPI_STATE_S4 && sc->acpi_s4bios)
254236772Siwasaki			status = AcpiEnterSleepStateS4bios();
255236772Siwasaki		else
256239340Sjkim			status = AcpiEnterSleepState(state);
257236772Siwasaki		if (ACPI_FAILURE(status)) {
258236772Siwasaki			device_printf(sc->acpi_dev,
259236772Siwasaki			    "AcpiEnterSleepState failed - %s\n",
260236772Siwasaki			    AcpiFormatException(status));
261236772Siwasaki			return (0);	/* couldn't sleep */
262236772Siwasaki		}
263236772Siwasaki
264335554Savg		if (acpi_susp_bounce)
265335554Savg			resumectx(pcb);
266335554Savg
267236772Siwasaki		for (;;)
268236772Siwasaki			ia32_pause();
269270850Sjhb	} else {
270335659Savg		/*
271335659Savg		 * Re-initialize console hardware as soon as possibe.
272335659Savg		 * No console output (e.g. printf) is allowed before
273335659Savg		 * this point.
274335659Savg		 */
275335659Savg		cnresume();
276271192Sjhb#ifdef __amd64__
277271192Sjhb		fpuresume(susppcbs[0]->sp_fpususpend);
278314210Skib#else
279273995Sjhb		npxresume(susppcbs[0]->sp_fpususpend);
280270850Sjhb#endif
281236772Siwasaki	}
282236772Siwasaki
283236772Siwasaki	return (1);	/* wakeup successfully */
284236772Siwasaki}
285236772Siwasaki
286236772Siwasakiint
287236772Siwasakiacpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result,
288236772Siwasaki    int intr_enabled)
289236772Siwasaki{
290236772Siwasaki
291236772Siwasaki	if (sleep_result == -1)
292236772Siwasaki		return (sleep_result);
293236772Siwasaki
294236772Siwasaki	if (!intr_enabled) {
295236772Siwasaki		/* Wakeup MD procedures in interrupt disabled context */
296236772Siwasaki		if (sleep_result == 1) {
297347700Smarkj			ucode_reload();
298236772Siwasaki			pmap_init_pat();
299236772Siwasaki			initializecpu();
300236772Siwasaki			PCPU_SET(switchtime, 0);
301236772Siwasaki			PCPU_SET(switchticks, ticks);
302279079Stijl#ifdef DEV_APIC
303278869Skib			lapic_xapic_mode();
304279079Stijl#endif
305236772Siwasaki#ifdef SMP
306236772Siwasaki			if (!CPU_EMPTY(&suspcpus))
307236772Siwasaki				acpi_wakeup_cpus(sc);
308236772Siwasaki#endif
309236772Siwasaki		}
310236772Siwasaki
311236772Siwasaki#ifdef SMP
312236772Siwasaki		if (!CPU_EMPTY(&suspcpus))
313331909Savg			resume_cpus(suspcpus);
314236772Siwasaki#endif
315236772Siwasaki		mca_resume();
316259782Sjhb#ifdef __amd64__
317259782Sjhb		if (vmm_resume_p != NULL)
318259782Sjhb			vmm_resume_p();
319259782Sjhb#endif
320255726Sgibbs		intr_resume(/*suspend_cancelled*/false);
321236772Siwasaki
322284583Sjkim		AcpiSetFirmwareWakingVector(0, 0);
323236772Siwasaki	} else {
324236772Siwasaki		/* Wakeup MD procedures in interrupt enabled context */
325236772Siwasaki		if (sleep_result == 1 && mem_range_softc.mr_op != NULL &&
326236772Siwasaki		    mem_range_softc.mr_op->reinit != NULL)
327236772Siwasaki			mem_range_softc.mr_op->reinit(&mem_range_softc);
328236772Siwasaki	}
329236772Siwasaki
330236772Siwasaki	return (sleep_result);
331236772Siwasaki}
332236772Siwasaki
333236772Siwasakistatic void *
334313128Smarkjacpi_alloc_wakeup_handler(void *wakepages[ACPI_WAKEPAGES])
335236772Siwasaki{
336236772Siwasaki	int		i;
337236772Siwasaki
338313128Smarkj	memset(wakepages, 0, ACPI_WAKEPAGES * sizeof(*wakepages));
339313128Smarkj
340236772Siwasaki	/*
341236772Siwasaki	 * Specify the region for our wakeup code.  We want it in the low 1 MB
342236772Siwasaki	 * region, excluding real mode IVT (0-0x3ff), BDA (0x400-0x4ff), EBDA
343236772Siwasaki	 * (less than 128KB, below 0xa0000, must be excluded by SMAP and DSDT),
344236772Siwasaki	 * and ROM area (0xa0000 and above).  The temporary page tables must be
345236772Siwasaki	 * page-aligned.
346236772Siwasaki	 */
347313128Smarkj	for (i = 0; i < ACPI_WAKEPAGES; i++) {
348313128Smarkj		wakepages[i] = contigmalloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT,
349313128Smarkj		    0x500, 0xa0000, PAGE_SIZE, 0ul);
350313128Smarkj		if (wakepages[i] == NULL) {
351313128Smarkj			printf("%s: can't alloc wake memory\n", __func__);
352313128Smarkj			goto freepages;
353313128Smarkj		}
354236772Siwasaki	}
355236772Siwasaki	if (EVENTHANDLER_REGISTER(power_resume, acpi_stop_beep, NULL,
356236772Siwasaki	    EVENTHANDLER_PRI_LAST) == NULL) {
357236772Siwasaki		printf("%s: can't register event handler\n", __func__);
358313128Smarkj		goto freepages;
359236772Siwasaki	}
360236772Siwasaki	susppcbs = malloc(mp_ncpus * sizeof(*susppcbs), M_DEVBUF, M_WAITOK);
361236772Siwasaki	for (i = 0; i < mp_ncpus; i++) {
362236772Siwasaki		susppcbs[i] = malloc(sizeof(**susppcbs), M_DEVBUF, M_WAITOK);
363271192Sjhb		susppcbs[i]->sp_fpususpend = alloc_fpusave(M_WAITOK);
364236772Siwasaki	}
365236772Siwasaki
366313128Smarkj	return (wakepages);
367313128Smarkj
368313128Smarkjfreepages:
369313128Smarkj	for (i = 0; i < ACPI_WAKEPAGES; i++)
370313128Smarkj		if (wakepages[i] != NULL)
371313128Smarkj			contigfree(wakepages[i], PAGE_SIZE, M_DEVBUF);
372313128Smarkj	return (NULL);
373236772Siwasaki}
374236772Siwasaki
375236772Siwasakivoid
376236772Siwasakiacpi_install_wakeup_handler(struct acpi_softc *sc)
377236772Siwasaki{
378313128Smarkj	static void	*wakeaddr;
379313128Smarkj	void		*wakepages[ACPI_WAKEPAGES];
380236772Siwasaki#ifdef __amd64__
381236772Siwasaki	uint64_t	*pt4, *pt3, *pt2;
382313128Smarkj	vm_paddr_t	pt4pa, pt3pa, pt2pa;
383236772Siwasaki	int		i;
384236772Siwasaki#endif
385236772Siwasaki
386236772Siwasaki	if (wakeaddr != NULL)
387236772Siwasaki		return;
388236772Siwasaki
389313128Smarkj	if (acpi_alloc_wakeup_handler(wakepages) == NULL)
390236772Siwasaki		return;
391236772Siwasaki
392313128Smarkj	wakeaddr = wakepages[0];
393236772Siwasaki	sc->acpi_wakeaddr = (vm_offset_t)wakeaddr;
394236772Siwasaki	sc->acpi_wakephys = vtophys(wakeaddr);
395236772Siwasaki
396313128Smarkj#ifdef __amd64__
397313128Smarkj	pt4 = wakepages[1];
398313128Smarkj	pt3 = wakepages[2];
399313128Smarkj	pt2 = wakepages[3];
400313128Smarkj	pt4pa = vtophys(pt4);
401313128Smarkj	pt3pa = vtophys(pt3);
402313128Smarkj	pt2pa = vtophys(pt2);
403313128Smarkj#endif
404236772Siwasaki
405313128Smarkj	bcopy(wakecode, (void *)sc->acpi_wakeaddr, sizeof(wakecode));
406313128Smarkj
407236772Siwasaki	/* Patch GDT base address, ljmp targets. */
408236772Siwasaki	WAKECODE_FIXUP((bootgdtdesc + 2), uint32_t,
409313128Smarkj	    sc->acpi_wakephys + bootgdt);
410236772Siwasaki	WAKECODE_FIXUP((wakeup_sw32 + 2), uint32_t,
411313128Smarkj	    sc->acpi_wakephys + wakeup_32);
412236772Siwasaki#ifdef __amd64__
413236772Siwasaki	WAKECODE_FIXUP((wakeup_sw64 + 1), uint32_t,
414313128Smarkj	    sc->acpi_wakephys + wakeup_64);
415313128Smarkj	WAKECODE_FIXUP(wakeup_pagetables, uint32_t, pt4pa);
416236772Siwasaki#endif
417236772Siwasaki
418236772Siwasaki	/* Save pointers to some global data. */
419236772Siwasaki	WAKECODE_FIXUP(wakeup_ret, void *, resumectx);
420237037Sjkim#ifndef __amd64__
421281495Skib#if defined(PAE) || defined(PAE_TABLES)
422236772Siwasaki	WAKECODE_FIXUP(wakeup_cr3, register_t, vtophys(kernel_pmap->pm_pdpt));
423236772Siwasaki#else
424236772Siwasaki	WAKECODE_FIXUP(wakeup_cr3, register_t, vtophys(kernel_pmap->pm_pdir));
425236772Siwasaki#endif
426236772Siwasaki
427313128Smarkj#else /* __amd64__ */
428236772Siwasaki	/* Create the initial 1GB replicated page tables */
429236772Siwasaki	for (i = 0; i < 512; i++) {
430236772Siwasaki		/*
431236772Siwasaki		 * Each slot of the level 4 pages points
432236772Siwasaki		 * to the same level 3 page
433236772Siwasaki		 */
434313128Smarkj		pt4[i] = (uint64_t)pt3pa;
435236772Siwasaki		pt4[i] |= PG_V | PG_RW | PG_U;
436236772Siwasaki
437236772Siwasaki		/*
438236772Siwasaki		 * Each slot of the level 3 pages points
439236772Siwasaki		 * to the same level 2 page
440236772Siwasaki		 */
441313128Smarkj		pt3[i] = (uint64_t)pt2pa;
442236772Siwasaki		pt3[i] |= PG_V | PG_RW | PG_U;
443236772Siwasaki
444236772Siwasaki		/* The level 2 page slots are mapped with 2MB pages for 1GB. */
445236772Siwasaki		pt2[i] = i * (2 * 1024 * 1024);
446236772Siwasaki		pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
447236772Siwasaki	}
448313128Smarkj#endif /* !__amd64__ */
449236772Siwasaki
450236772Siwasaki	if (bootverbose)
451236772Siwasaki		device_printf(sc->acpi_dev, "wakeup code va %#jx pa %#jx\n",
452236772Siwasaki		    (uintmax_t)sc->acpi_wakeaddr, (uintmax_t)sc->acpi_wakephys);
453236772Siwasaki}
454