Page MenuHomeFreeBSD

D7154.id18216.diff
No OneTemporary

D7154.id18216.diff

Index: sys/x86/acpica/acpi_wakeup.c
===================================================================
--- sys/x86/acpica/acpi_wakeup.c
+++ sys/x86/acpica/acpi_wakeup.c
@@ -88,7 +88,7 @@
static struct susppcb **susppcbs;
#endif
-static void *acpi_alloc_wakeup_handler(void);
+static void *acpi_alloc_wakeup_handler(void **);
static void acpi_stop_beep(void *);
#ifdef SMP
@@ -102,10 +102,10 @@
#define ACPI_PAGETABLES 0
#endif
-#define WAKECODE_VADDR(sc) \
- ((sc)->acpi_wakeaddr + (ACPI_PAGETABLES * PAGE_SIZE))
-#define WAKECODE_PADDR(sc) \
- ((sc)->acpi_wakephys + (ACPI_PAGETABLES * PAGE_SIZE))
+#define ACPI_WAKEPAGES (ACPI_PAGETABLES + 1)
+
+#define WAKECODE_VADDR(sc) (sc)->acpi_wakeaddr
+#define WAKECODE_PADDR(sc) (sc)->acpi_wakephys
#define WAKECODE_FIXUP(offset, type, val) do { \
type *addr; \
addr = (type *)(WAKECODE_VADDR(sc) + offset); \
@@ -309,9 +309,8 @@
}
static void *
-acpi_alloc_wakeup_handler(void)
+acpi_alloc_wakeup_handler(void *wakepages[ACPI_WAKEPAGES])
{
- void *wakeaddr;
int i;
/*
@@ -321,18 +320,18 @@
* and ROM area (0xa0000 and above). The temporary page tables must be
* page-aligned.
*/
- wakeaddr = contigmalloc((ACPI_PAGETABLES + 1) * PAGE_SIZE, M_DEVBUF,
- M_NOWAIT, 0x500, 0xa0000, PAGE_SIZE, 0ul);
- if (wakeaddr == NULL) {
- printf("%s: can't alloc wake memory\n", __func__);
- return (NULL);
+ for (i = 0; i < ACPI_WAKEPAGES; i++) {
+ wakepages[i] = contigmalloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT,
+ 0x500, 0xa0000, PAGE_SIZE, 0ul);
+ if (wakepages[i] == NULL) {
+ printf("%s: can't alloc wake memory\n", __func__);
+ goto freepages;
+ }
}
if (EVENTHANDLER_REGISTER(power_resume, acpi_stop_beep, NULL,
EVENTHANDLER_PRI_LAST) == NULL) {
printf("%s: can't register event handler\n", __func__);
- contigfree(wakeaddr, (ACPI_PAGETABLES + 1) * PAGE_SIZE,
- M_DEVBUF);
- return (NULL);
+ goto freepages;
}
susppcbs = malloc(mp_ncpus * sizeof(*susppcbs), M_DEVBUF, M_WAITOK);
for (i = 0; i < mp_ncpus; i++) {
@@ -340,28 +339,44 @@
susppcbs[i]->sp_fpususpend = alloc_fpusave(M_WAITOK);
}
- return (wakeaddr);
+ return (wakepages);
+
+freepages:
+ for (i = 0; i < ACPI_WAKEPAGES; i++)
+ if (wakepages[i] != NULL)
+ contigfree(wakepages[i], PAGE_SIZE, M_DEVBUF);
+ return (NULL);
}
void
acpi_install_wakeup_handler(struct acpi_softc *sc)
{
- static void *wakeaddr = NULL;
+ static void *wakeaddr;
+ void *wakepages[ACPI_WAKEPAGES];
#ifdef __amd64__
uint64_t *pt4, *pt3, *pt2;
+ vm_paddr_t pt3pa, pt2pa;
int i;
#endif
if (wakeaddr != NULL)
return;
- wakeaddr = acpi_alloc_wakeup_handler();
- if (wakeaddr == NULL)
+ if (acpi_alloc_wakeup_handler(wakepages) == NULL)
return;
+ wakeaddr = wakepages[0];
sc->acpi_wakeaddr = (vm_offset_t)wakeaddr;
sc->acpi_wakephys = vtophys(wakeaddr);
+#ifdef __amd64__
+ pt4 = wakepages[1];
+ pt3 = wakepages[2];
+ pt2 = wakepages[3];
+ pt3pa = vtophys(pt3);
+ pt2pa = vtophys(pt2);
+#endif
+
bcopy(wakecode, (void *)WAKECODE_VADDR(sc), sizeof(wakecode));
/* Patch GDT base address, ljmp targets. */
@@ -372,7 +387,7 @@
#ifdef __amd64__
WAKECODE_FIXUP((wakeup_sw64 + 1), uint32_t,
WAKECODE_PADDR(sc) + wakeup_64);
- WAKECODE_FIXUP(wakeup_pagetables, uint32_t, sc->acpi_wakephys);
+ WAKECODE_FIXUP(wakeup_pagetables, uint32_t, vtophys(pt4));
#endif
/* Save pointers to some global data. */
@@ -384,33 +399,28 @@
WAKECODE_FIXUP(wakeup_cr3, register_t, vtophys(kernel_pmap->pm_pdir));
#endif
-#else
- /* Build temporary page tables below realmode code. */
- pt4 = wakeaddr;
- pt3 = pt4 + (PAGE_SIZE) / sizeof(uint64_t);
- pt2 = pt3 + (PAGE_SIZE) / sizeof(uint64_t);
-
+#else /* __amd64__ */
/* 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] = (uint64_t)pt3pa;
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] = (uint64_t)pt2pa;
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;
}
-#endif
+#endif /* !__amd64__ */
if (bootverbose)
device_printf(sc->acpi_dev, "wakeup code va %#jx pa %#jx\n",

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 13, 5:51 AM (18 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26923048
Default Alt Text
D7154.id18216.diff (4 KB)

Event Timeline